1*c6d43980SLemover/*************************************************************************************** 2*c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*c6d43980SLemover* 4*c6d43980SLemover* XiangShan is licensed under Mulan PSL v2. 5*c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 6*c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at: 7*c6d43980SLemover* http://license.coscl.org.cn/MulanPSL2 8*c6d43980SLemover* 9*c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10*c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11*c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12*c6d43980SLemover* 13*c6d43980SLemover* See the Mulan PSL v2 for more details. 14*c6d43980SLemover***************************************************************************************/ 15*c6d43980SLemover 161db30e61Slinjiaweipackage device 171db30e61Slinjiawei 181db30e61Slinjiaweiimport chisel3._ 191db30e61Slinjiaweiimport chisel3.util._ 201db30e61Slinjiaweiimport utils._ 211db30e61Slinjiaweiimport freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, RegionType, TransferSizes} 221db30e61Slinjiaweiimport chipsalliance.rocketchip.config.Parameters 231db30e61Slinjiaweiimport freechips.rocketchip.amba.axi4.{AXI4Parameters, AXI4SlaveNode, AXI4SlaveParameters, AXI4SlavePortParameters} 241db30e61Slinjiawei 251db30e61Slinjiaweiabstract class AXI4SlaveModule[T <: Data] 261db30e61Slinjiawei( 27a2e9bde6SAllen address: Seq[AddressSet], 281db30e61Slinjiawei executable: Boolean = true, 291db30e61Slinjiawei beatBytes: Int = 8, 301db30e61Slinjiawei burstLen: Int = 1, 311db30e61Slinjiawei val _extra: T = null 321db30e61Slinjiawei)(implicit p: Parameters) extends LazyModule { 331db30e61Slinjiawei 341db30e61Slinjiawei val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters( 351db30e61Slinjiawei Seq(AXI4SlaveParameters( 36a2e9bde6SAllen address, 371db30e61Slinjiawei regionType = RegionType.UNCACHED, 381db30e61Slinjiawei executable = executable, 391db30e61Slinjiawei supportsWrite = TransferSizes(1, beatBytes * burstLen), 401db30e61Slinjiawei supportsRead = TransferSizes(1, beatBytes * burstLen), 411db30e61Slinjiawei interleavedId = Some(0) 421db30e61Slinjiawei )), 431db30e61Slinjiawei beatBytes = beatBytes 441db30e61Slinjiawei ))) 451db30e61Slinjiawei 461db30e61Slinjiawei lazy val module = new AXI4SlaveModuleImp[T](this) 471db30e61Slinjiawei 481db30e61Slinjiawei} 491db30e61Slinjiawei 501db30e61Slinjiaweiclass AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T]) 515c5bd416Sljw extends LazyModuleImp(outer) 521db30e61Slinjiawei{ 531db30e61Slinjiawei val io = IO(new Bundle { 54956d83c0Slinjiawei val extra = if(outer._extra == null) None else Some(outer._extra.cloneType) 551db30e61Slinjiawei }) 561db30e61Slinjiawei 571db30e61Slinjiawei val (in, edge) = outer.node.in.head 5855fc3133SAllen // do not let MMIO AXI signals optimized out 5955fc3133SAllen chisel3.dontTouch(in) 6055fc3133SAllen 611db30e61Slinjiawei 62e2801f97Slinjiawei// val timer = GTimer() 631db30e61Slinjiawei when(in.ar.fire()){ 64e2801f97Slinjiawei XSDebug(p"[ar] addr: ${Hexadecimal(in.ar.bits.addr)} " + 651db30e61Slinjiawei p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " + 661db30e61Slinjiawei p"id: ${in.ar.bits.id}\n" 671db30e61Slinjiawei ) 681db30e61Slinjiawei } 691db30e61Slinjiawei when(in.aw.fire()){ 70e2801f97Slinjiawei XSDebug(p"[aw] addr: ${Hexadecimal(in.aw.bits.addr)} " + 711db30e61Slinjiawei p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " + 721db30e61Slinjiawei p"id: ${in.aw.bits.id}\n" 731db30e61Slinjiawei ) 741db30e61Slinjiawei } 751db30e61Slinjiawei when(in.w.fire()){ 7624b11ca3Slinjiawei XSDebug(p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n") 771db30e61Slinjiawei } 781db30e61Slinjiawei when(in.b.fire()){ 79e2801f97Slinjiawei XSDebug(p"[b] id: ${in.b.bits.id}\n") 801db30e61Slinjiawei } 811db30e61Slinjiawei when(in.r.fire()){ 8224b11ca3Slinjiawei XSDebug(p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n") 831db30e61Slinjiawei } 841db30e61Slinjiawei 85efc6a777Slinjiawei when(in.aw.fire()){ 86efc6a777Slinjiawei assert(in.aw.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 87efc6a777Slinjiawei } 88efc6a777Slinjiawei 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){ 98075891a7Slinjiawei when(in.ar.fire()){ 99075891a7Slinjiawei state := s_rdata 100075891a7Slinjiawei } 101075891a7Slinjiawei when(in.aw.fire()){ 102075891a7Slinjiawei state := s_wdata 103075891a7Slinjiawei } 104075891a7Slinjiawei } 105075891a7Slinjiawei is(s_rdata){ 106075891a7Slinjiawei when(in.r.fire() && in.r.bits.last){ 107075891a7Slinjiawei state := s_idle 108075891a7Slinjiawei } 109075891a7Slinjiawei } 110075891a7Slinjiawei is(s_wdata){ 111075891a7Slinjiawei when(in.w.fire() && in.w.bits.last){ 112075891a7Slinjiawei state := s_wresp 113075891a7Slinjiawei } 114075891a7Slinjiawei } 115075891a7Slinjiawei is(s_wresp){ 116075891a7Slinjiawei when(in.b.fire()){ 117075891a7Slinjiawei state := s_idle 118075891a7Slinjiawei } 119075891a7Slinjiawei } 120075891a7Slinjiawei } 121075891a7Slinjiawei 122075891a7Slinjiawei 1231db30e61Slinjiawei val fullMask = MaskExpand(in.w.bits.strb) 1241db30e61Slinjiawei 1251db30e61Slinjiawei 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) 1301db30e61Slinjiawei val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 131efc6a777Slinjiawei raddr := HoldUnless(in.ar.bits.addr, in.ar.fire()) 1321db30e61Slinjiawei in.r.bits.last := (c.value === len) 133efc6a777Slinjiawei 1341db30e61Slinjiawei when(in.r.fire()) { 1351db30e61Slinjiawei c.inc() 1361db30e61Slinjiawei when(in.r.bits.last) { 1371db30e61Slinjiawei c.value := 0.U 1381db30e61Slinjiawei } 1391db30e61Slinjiawei } 1401db30e61Slinjiawei 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) 1601db30e61Slinjiawei waddr := HoldUnless(in.aw.bits.addr, in.aw.fire()) 1611db30e61Slinjiawei 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 1761db30e61Slinjiawei in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire()) 1771db30e61Slinjiawei in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire()) 1781db30e61Slinjiawei in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire()) 1791db30e61Slinjiawei in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire()) 1801db30e61Slinjiawei} 181