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 { 39956d83c0Slinjiawei 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 67*075891a7Slinjiawei 68*075891a7Slinjiawei val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4) 69*075891a7Slinjiawei 70*075891a7Slinjiawei val state = RegInit(s_idle) 71*075891a7Slinjiawei 72*075891a7Slinjiawei switch(state){ 73*075891a7Slinjiawei is(s_idle){ 74*075891a7Slinjiawei when(in.ar.fire()){ 75*075891a7Slinjiawei state := s_rdata 76*075891a7Slinjiawei } 77*075891a7Slinjiawei when(in.aw.fire()){ 78*075891a7Slinjiawei state := s_wdata 79*075891a7Slinjiawei } 80*075891a7Slinjiawei } 81*075891a7Slinjiawei is(s_rdata){ 82*075891a7Slinjiawei when(in.r.fire() && in.r.bits.last){ 83*075891a7Slinjiawei state := s_idle 84*075891a7Slinjiawei } 85*075891a7Slinjiawei } 86*075891a7Slinjiawei is(s_wdata){ 87*075891a7Slinjiawei when(in.w.fire() && in.w.bits.last){ 88*075891a7Slinjiawei state := s_wresp 89*075891a7Slinjiawei } 90*075891a7Slinjiawei } 91*075891a7Slinjiawei is(s_wresp){ 92*075891a7Slinjiawei when(in.b.fire()){ 93*075891a7Slinjiawei state := s_idle 94*075891a7Slinjiawei } 95*075891a7Slinjiawei } 96*075891a7Slinjiawei } 97*075891a7Slinjiawei 98*075891a7Slinjiawei 991db30e61Slinjiawei val fullMask = MaskExpand(in.w.bits.strb) 1001db30e61Slinjiawei 1011db30e61Slinjiawei def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask) 1021db30e61Slinjiawei 1031db30e61Slinjiawei val raddr = Wire(UInt()) 1041db30e61Slinjiawei val ren = Wire(Bool()) 1051db30e61Slinjiawei val (readBeatCnt, rLast) = { 1061db30e61Slinjiawei val c = Counter(256) 1071db30e61Slinjiawei val beatCnt = Counter(256) 1081db30e61Slinjiawei val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 1091db30e61Slinjiawei val burst = HoldUnless(in.ar.bits.burst, in.ar.fire()) 1101db30e61Slinjiawei val wrapAddr = in.ar.bits.addr & (~(in.ar.bits.len << in.ar.bits.size)).asUInt() 1111db30e61Slinjiawei raddr := HoldUnless(wrapAddr, in.ar.fire()) 1121db30e61Slinjiawei in.r.bits.last := (c.value === len) 1131db30e61Slinjiawei when(ren) { 1141db30e61Slinjiawei beatCnt.inc() 1151db30e61Slinjiawei when(burst === AXI4Parameters.BURST_WRAP && beatCnt.value === len) { 1161db30e61Slinjiawei beatCnt.value := 0.U 1171db30e61Slinjiawei } 1181db30e61Slinjiawei } 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()) { 1261db30e61Slinjiawei beatCnt.value := (in.ar.bits.addr >> in.ar.bits.size).asUInt() & in.ar.bits.len 1271db30e61Slinjiawei when(in.ar.bits.len =/= 0.U && in.ar.bits.burst === AXI4Parameters.BURST_WRAP) { 1281db30e61Slinjiawei assert(in.ar.bits.len === 1.U || in.ar.bits.len === 3.U || 1291db30e61Slinjiawei in.ar.bits.len === 7.U || in.ar.bits.len === 15.U) 1301db30e61Slinjiawei } 1311db30e61Slinjiawei } 1321db30e61Slinjiawei (beatCnt.value, in.r.bits.last) 1331db30e61Slinjiawei } 1341db30e61Slinjiawei 1351db30e61Slinjiawei val r_busy = BoolStopWatch(in.ar.fire(), in.r.fire() && rLast, startHighPriority = true) 136*075891a7Slinjiawei in.ar.ready := state === s_idle 1371db30e61Slinjiawei in.r.bits.resp := AXI4Parameters.RESP_OKAY 1381db30e61Slinjiawei ren := RegNext(in.ar.fire()) || (in.r.fire() && !rLast) 139*075891a7Slinjiawei 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 155*075891a7Slinjiawei in.aw.ready := state === s_idle 156*075891a7Slinjiawei in.w.ready := state === s_wdata 157*075891a7Slinjiawei 1581db30e61Slinjiawei in.b.bits.resp := AXI4Parameters.RESP_OKAY 159*075891a7Slinjiawei 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