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( 121db30e61Slinjiawei address: 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( 211db30e61Slinjiawei Seq(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]) 361db30e61Slinjiawei extends LazyModuleImp(outer) 371db30e61Slinjiawei{ 381db30e61Slinjiawei val io = IO(new Bundle { 39*956d83c0Slinjiawei val extra = if(outer._extra == null) None else Some(outer._extra.cloneType) 401db30e61Slinjiawei }) 411db30e61Slinjiawei 421db30e61Slinjiawei val (in, edge) = outer.node.in.head 431db30e61Slinjiawei 441db30e61Slinjiawei val timer = GTimer() 451db30e61Slinjiawei when(in.ar.fire()){ 461db30e61Slinjiawei printf(p"[$timer][ar] addr: ${Hexadecimal(in.ar.bits.addr)} " + 471db30e61Slinjiawei p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " + 481db30e61Slinjiawei p"id: ${in.ar.bits.id}\n" 491db30e61Slinjiawei ) 501db30e61Slinjiawei } 511db30e61Slinjiawei when(in.aw.fire()){ 521db30e61Slinjiawei printf(p"[$timer][aw] addr: ${Hexadecimal(in.aw.bits.addr)} " + 531db30e61Slinjiawei p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " + 541db30e61Slinjiawei p"id: ${in.aw.bits.id}\n" 551db30e61Slinjiawei ) 561db30e61Slinjiawei } 571db30e61Slinjiawei when(in.w.fire()){ 581db30e61Slinjiawei printf(p"[$timer][w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last}\n") 591db30e61Slinjiawei } 601db30e61Slinjiawei when(in.b.fire()){ 611db30e61Slinjiawei printf(p"[$timer][b] id: ${in.b.bits.id}\n") 621db30e61Slinjiawei } 631db30e61Slinjiawei when(in.r.fire()){ 641db30e61Slinjiawei printf(p"[$timer][r] id: ${in.r.bits.id}\n") 651db30e61Slinjiawei } 661db30e61Slinjiawei 671db30e61Slinjiawei val fullMask = MaskExpand(in.w.bits.strb) 681db30e61Slinjiawei 691db30e61Slinjiawei def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask) 701db30e61Slinjiawei 711db30e61Slinjiawei val raddr = Wire(UInt()) 721db30e61Slinjiawei val ren = Wire(Bool()) 731db30e61Slinjiawei val (readBeatCnt, rLast) = { 741db30e61Slinjiawei val c = Counter(256) 751db30e61Slinjiawei val beatCnt = Counter(256) 761db30e61Slinjiawei val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 771db30e61Slinjiawei val burst = HoldUnless(in.ar.bits.burst, in.ar.fire()) 781db30e61Slinjiawei val wrapAddr = in.ar.bits.addr & (~(in.ar.bits.len << in.ar.bits.size)).asUInt() 791db30e61Slinjiawei raddr := HoldUnless(wrapAddr, in.ar.fire()) 801db30e61Slinjiawei in.r.bits.last := (c.value === len) 811db30e61Slinjiawei when(ren) { 821db30e61Slinjiawei beatCnt.inc() 831db30e61Slinjiawei when(burst === AXI4Parameters.BURST_WRAP && beatCnt.value === len) { 841db30e61Slinjiawei beatCnt.value := 0.U 851db30e61Slinjiawei } 861db30e61Slinjiawei } 871db30e61Slinjiawei when(in.r.fire()) { 881db30e61Slinjiawei c.inc() 891db30e61Slinjiawei when(in.r.bits.last) { 901db30e61Slinjiawei c.value := 0.U 911db30e61Slinjiawei } 921db30e61Slinjiawei } 931db30e61Slinjiawei when(in.ar.fire()) { 941db30e61Slinjiawei beatCnt.value := (in.ar.bits.addr >> in.ar.bits.size).asUInt() & in.ar.bits.len 951db30e61Slinjiawei when(in.ar.bits.len =/= 0.U && in.ar.bits.burst === AXI4Parameters.BURST_WRAP) { 961db30e61Slinjiawei assert(in.ar.bits.len === 1.U || in.ar.bits.len === 3.U || 971db30e61Slinjiawei in.ar.bits.len === 7.U || in.ar.bits.len === 15.U) 981db30e61Slinjiawei } 991db30e61Slinjiawei } 1001db30e61Slinjiawei (beatCnt.value, in.r.bits.last) 1011db30e61Slinjiawei } 1021db30e61Slinjiawei 1031db30e61Slinjiawei val r_busy = BoolStopWatch(in.ar.fire(), in.r.fire() && rLast, startHighPriority = true) 1041db30e61Slinjiawei in.ar.ready := in.r.ready || !r_busy 1051db30e61Slinjiawei in.r.bits.resp := AXI4Parameters.RESP_OKAY 1061db30e61Slinjiawei ren := RegNext(in.ar.fire()) || (in.r.fire() && !rLast) 1071db30e61Slinjiawei in.r.valid := BoolStopWatch(ren && (in.ar.fire() || r_busy), in.r.fire(), startHighPriority = true) 1081db30e61Slinjiawei 1091db30e61Slinjiawei 1101db30e61Slinjiawei val waddr = Wire(UInt()) 1111db30e61Slinjiawei val (writeBeatCnt, wLast) = { 1121db30e61Slinjiawei val c = Counter(256) 1131db30e61Slinjiawei waddr := HoldUnless(in.aw.bits.addr, in.aw.fire()) 1141db30e61Slinjiawei when(in.w.fire()) { 1151db30e61Slinjiawei c.inc() 1161db30e61Slinjiawei when(in.w.bits.last) { 1171db30e61Slinjiawei c.value := 0.U 1181db30e61Slinjiawei } 1191db30e61Slinjiawei } 1201db30e61Slinjiawei (c.value, in.w.bits.last) 1211db30e61Slinjiawei } 1221db30e61Slinjiawei 1231db30e61Slinjiawei val w_busy = BoolStopWatch(in.aw.fire(), in.b.fire(), startHighPriority = true) 1241db30e61Slinjiawei in.aw.ready := !w_busy 1251db30e61Slinjiawei in.w.ready := in.aw.valid || (w_busy) 1261db30e61Slinjiawei in.b.bits.resp := AXI4Parameters.RESP_OKAY 1271db30e61Slinjiawei in.b.valid := BoolStopWatch(in.w.fire() && wLast, in.b.fire(), startHighPriority = true) 1281db30e61Slinjiawei 1291db30e61Slinjiawei in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire()) 1301db30e61Slinjiawei in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire()) 1311db30e61Slinjiawei in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire()) 1321db30e61Slinjiawei in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire()) 1331db30e61Slinjiawei} 134