1c6d43980SLemover/*************************************************************************************** 2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory 4c6d43980SLemover* 5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2. 6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at: 8c6d43980SLemover* http://license.coscl.org.cn/MulanPSL2 9c6d43980SLemover* 10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13c6d43980SLemover* 14c6d43980SLemover* See the Mulan PSL v2 for more details. 15c6d43980SLemover***************************************************************************************/ 16c6d43980SLemover 171db30e61Slinjiaweipackage device 181db30e61Slinjiawei 191db30e61Slinjiaweiimport chisel3._ 201db30e61Slinjiaweiimport chisel3.util._ 211db30e61Slinjiaweiimport utils._ 223c02ee8fSwakafaimport utility._ 231db30e61Slinjiaweiimport freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, RegionType, TransferSizes} 248891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters 251db30e61Slinjiaweiimport freechips.rocketchip.amba.axi4.{AXI4Parameters, AXI4SlaveNode, AXI4SlaveParameters, AXI4SlavePortParameters} 261db30e61Slinjiawei 271db30e61Slinjiaweiabstract class AXI4SlaveModule[T <: Data] 281db30e61Slinjiawei( 29a2e9bde6SAllen address: Seq[AddressSet], 301db30e61Slinjiawei executable: Boolean = true, 311db30e61Slinjiawei beatBytes: Int = 8, 321db30e61Slinjiawei burstLen: Int = 1, 331db30e61Slinjiawei val _extra: T = null 341db30e61Slinjiawei)(implicit p: Parameters) extends LazyModule { 351db30e61Slinjiawei 361db30e61Slinjiawei val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters( 371db30e61Slinjiawei Seq(AXI4SlaveParameters( 38a2e9bde6SAllen address, 391db30e61Slinjiawei regionType = RegionType.UNCACHED, 401db30e61Slinjiawei executable = executable, 411db30e61Slinjiawei supportsWrite = TransferSizes(1, beatBytes * burstLen), 421db30e61Slinjiawei supportsRead = TransferSizes(1, beatBytes * burstLen), 431db30e61Slinjiawei interleavedId = Some(0) 441db30e61Slinjiawei )), 451db30e61Slinjiawei beatBytes = beatBytes 461db30e61Slinjiawei ))) 471db30e61Slinjiawei 481db30e61Slinjiawei lazy val module = new AXI4SlaveModuleImp[T](this) 491db30e61Slinjiawei 501db30e61Slinjiawei} 511db30e61Slinjiawei 521db30e61Slinjiaweiclass AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T]) 535c5bd416Sljw extends LazyModuleImp(outer) 541db30e61Slinjiawei{ 551db30e61Slinjiawei val io = IO(new Bundle { 56956d83c0Slinjiawei val extra = if(outer._extra == null) None else Some(outer._extra.cloneType) 571db30e61Slinjiawei }) 581db30e61Slinjiawei 591db30e61Slinjiawei val (in, edge) = outer.node.in.head 6055fc3133SAllen // do not let MMIO AXI signals optimized out 6155fc3133SAllen chisel3.dontTouch(in) 6255fc3133SAllen 631db30e61Slinjiawei 64e2801f97Slinjiawei// val timer = GTimer() 65*8b33cd30Sklin02 XSDebug(in.ar.fire, 66*8b33cd30Sklin02 p"[ar] addr: ${Hexadecimal(in.ar.bits.addr)} " + 671db30e61Slinjiawei p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " + 681db30e61Slinjiawei p"id: ${in.ar.bits.id}\n" 691db30e61Slinjiawei ) 70*8b33cd30Sklin02 XSDebug(in.aw.fire, 71*8b33cd30Sklin02 p"[aw] addr: ${Hexadecimal(in.aw.bits.addr)} " + 721db30e61Slinjiawei p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " + 731db30e61Slinjiawei p"id: ${in.aw.bits.id}\n" 741db30e61Slinjiawei ) 75*8b33cd30Sklin02 XSDebug(in.w.fire, 76*8b33cd30Sklin02 p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n" 77*8b33cd30Sklin02 ) 78*8b33cd30Sklin02 XSDebug(in.b.fire, 79*8b33cd30Sklin02 p"[b] id: ${in.b.bits.id}\n" 80*8b33cd30Sklin02 ) 81*8b33cd30Sklin02 XSDebug(in.r.fire, 82*8b33cd30Sklin02 p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n" 83*8b33cd30Sklin02 ) 841db30e61Slinjiawei 85935edac4STang Haojin when(in.aw.fire){ 86efc6a777Slinjiawei assert(in.aw.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 87efc6a777Slinjiawei } 88935edac4STang Haojin when(in.ar.fire){ 89efc6a777Slinjiawei assert(in.ar.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 90efc6a777Slinjiawei } 91075891a7Slinjiawei 922195ebbdSYinan Xu val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4) 93075891a7Slinjiawei 942195ebbdSYinan Xu val state = RegInit(s_idle) 95075891a7Slinjiawei 96075891a7Slinjiawei switch(state){ 97075891a7Slinjiawei is(s_idle){ 98935edac4STang Haojin when(in.ar.fire){ 99075891a7Slinjiawei state := s_rdata 100075891a7Slinjiawei } 101935edac4STang Haojin when(in.aw.fire){ 102075891a7Slinjiawei state := s_wdata 103075891a7Slinjiawei } 104075891a7Slinjiawei } 105075891a7Slinjiawei is(s_rdata){ 106935edac4STang Haojin when(in.r.fire && in.r.bits.last){ 107075891a7Slinjiawei state := s_idle 108075891a7Slinjiawei } 109075891a7Slinjiawei } 110075891a7Slinjiawei is(s_wdata){ 111935edac4STang Haojin when(in.w.fire && in.w.bits.last){ 112075891a7Slinjiawei state := s_wresp 113075891a7Slinjiawei } 114075891a7Slinjiawei } 115075891a7Slinjiawei is(s_wresp){ 116935edac4STang Haojin when(in.b.fire){ 117075891a7Slinjiawei state := s_idle 118075891a7Slinjiawei } 119075891a7Slinjiawei } 120075891a7Slinjiawei } 121075891a7Slinjiawei 122075891a7Slinjiawei 1231db30e61Slinjiawei val fullMask = MaskExpand(in.w.bits.strb) 1241db30e61Slinjiawei 125935edac4STang Haojin def genWdata(originData: UInt) = (originData & (~fullMask).asUInt) | (in.w.bits.data & fullMask) 1261db30e61Slinjiawei 1271db30e61Slinjiawei val raddr = Wire(UInt()) 1281db30e61Slinjiawei val (readBeatCnt, rLast) = { 1291db30e61Slinjiawei val c = Counter(256) 130935edac4STang Haojin val len = HoldUnless(in.ar.bits.len, in.ar.fire) 131935edac4STang Haojin raddr := HoldUnless(in.ar.bits.addr, in.ar.fire) 1321db30e61Slinjiawei in.r.bits.last := (c.value === len) 133efc6a777Slinjiawei 134935edac4STang Haojin when(in.r.fire) { 1351db30e61Slinjiawei c.inc() 1361db30e61Slinjiawei when(in.r.bits.last) { 1371db30e61Slinjiawei c.value := 0.U 1381db30e61Slinjiawei } 1391db30e61Slinjiawei } 140935edac4STang Haojin when(in.ar.fire) { 141efc6a777Slinjiawei assert( 142efc6a777Slinjiawei in.ar.bits.len === 0.U || 143efc6a777Slinjiawei in.ar.bits.len === 1.U || 144efc6a777Slinjiawei in.ar.bits.len === 3.U || 145efc6a777Slinjiawei in.ar.bits.len === 7.U || 146efc6a777Slinjiawei in.ar.bits.len === 15.U 147efc6a777Slinjiawei ) 1481db30e61Slinjiawei } 149efc6a777Slinjiawei (c.value, in.r.bits.last) 1501db30e61Slinjiawei } 1511db30e61Slinjiawei 152075891a7Slinjiawei in.ar.ready := state === s_idle 1531db30e61Slinjiawei in.r.bits.resp := AXI4Parameters.RESP_OKAY 154075891a7Slinjiawei in.r.valid := state === s_rdata 1551db30e61Slinjiawei 1561db30e61Slinjiawei 1571db30e61Slinjiawei val waddr = Wire(UInt()) 1581db30e61Slinjiawei val (writeBeatCnt, wLast) = { 1591db30e61Slinjiawei val c = Counter(256) 160935edac4STang Haojin waddr := HoldUnless(in.aw.bits.addr, in.aw.fire) 161935edac4STang Haojin when(in.w.fire) { 1621db30e61Slinjiawei c.inc() 1631db30e61Slinjiawei when(in.w.bits.last) { 1641db30e61Slinjiawei c.value := 0.U 1651db30e61Slinjiawei } 1661db30e61Slinjiawei } 1671db30e61Slinjiawei (c.value, in.w.bits.last) 1681db30e61Slinjiawei } 1691db30e61Slinjiawei 1706c6d537cSAllen in.aw.ready := state === s_idle && !in.ar.valid 171075891a7Slinjiawei in.w.ready := state === s_wdata 172075891a7Slinjiawei 1731db30e61Slinjiawei in.b.bits.resp := AXI4Parameters.RESP_OKAY 174075891a7Slinjiawei in.b.valid := state===s_wresp 1751db30e61Slinjiawei 176935edac4STang Haojin in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire) 177935edac4STang Haojin in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire) 178935edac4STang Haojin in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire) 179935edac4STang Haojin in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire) 1801db30e61Slinjiawei} 181