1c6d43980SLemover/*************************************************************************************** 2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*f320e0f0SYinan 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._ 221db30e61Slinjiaweiimport freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, RegionType, TransferSizes} 231db30e61Slinjiaweiimport chipsalliance.rocketchip.config.Parameters 241db30e61Slinjiaweiimport freechips.rocketchip.amba.axi4.{AXI4Parameters, AXI4SlaveNode, AXI4SlaveParameters, AXI4SlavePortParameters} 251db30e61Slinjiawei 261db30e61Slinjiaweiabstract class AXI4SlaveModule[T <: Data] 271db30e61Slinjiawei( 28a2e9bde6SAllen address: Seq[AddressSet], 291db30e61Slinjiawei executable: Boolean = true, 301db30e61Slinjiawei beatBytes: Int = 8, 311db30e61Slinjiawei burstLen: Int = 1, 321db30e61Slinjiawei val _extra: T = null 331db30e61Slinjiawei)(implicit p: Parameters) extends LazyModule { 341db30e61Slinjiawei 351db30e61Slinjiawei val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters( 361db30e61Slinjiawei Seq(AXI4SlaveParameters( 37a2e9bde6SAllen address, 381db30e61Slinjiawei regionType = RegionType.UNCACHED, 391db30e61Slinjiawei executable = executable, 401db30e61Slinjiawei supportsWrite = TransferSizes(1, beatBytes * burstLen), 411db30e61Slinjiawei supportsRead = TransferSizes(1, beatBytes * burstLen), 421db30e61Slinjiawei interleavedId = Some(0) 431db30e61Slinjiawei )), 441db30e61Slinjiawei beatBytes = beatBytes 451db30e61Slinjiawei ))) 461db30e61Slinjiawei 471db30e61Slinjiawei lazy val module = new AXI4SlaveModuleImp[T](this) 481db30e61Slinjiawei 491db30e61Slinjiawei} 501db30e61Slinjiawei 511db30e61Slinjiaweiclass AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T]) 525c5bd416Sljw extends LazyModuleImp(outer) 531db30e61Slinjiawei{ 541db30e61Slinjiawei val io = IO(new Bundle { 55956d83c0Slinjiawei val extra = if(outer._extra == null) None else Some(outer._extra.cloneType) 561db30e61Slinjiawei }) 571db30e61Slinjiawei 581db30e61Slinjiawei val (in, edge) = outer.node.in.head 5955fc3133SAllen // do not let MMIO AXI signals optimized out 6055fc3133SAllen chisel3.dontTouch(in) 6155fc3133SAllen 621db30e61Slinjiawei 63e2801f97Slinjiawei// val timer = GTimer() 641db30e61Slinjiawei when(in.ar.fire()){ 65e2801f97Slinjiawei XSDebug(p"[ar] addr: ${Hexadecimal(in.ar.bits.addr)} " + 661db30e61Slinjiawei p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " + 671db30e61Slinjiawei p"id: ${in.ar.bits.id}\n" 681db30e61Slinjiawei ) 691db30e61Slinjiawei } 701db30e61Slinjiawei when(in.aw.fire()){ 71e2801f97Slinjiawei XSDebug(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 ) 751db30e61Slinjiawei } 761db30e61Slinjiawei when(in.w.fire()){ 7724b11ca3Slinjiawei XSDebug(p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n") 781db30e61Slinjiawei } 791db30e61Slinjiawei when(in.b.fire()){ 80e2801f97Slinjiawei XSDebug(p"[b] id: ${in.b.bits.id}\n") 811db30e61Slinjiawei } 821db30e61Slinjiawei when(in.r.fire()){ 8324b11ca3Slinjiawei XSDebug(p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n") 841db30e61Slinjiawei } 851db30e61Slinjiawei 86efc6a777Slinjiawei when(in.aw.fire()){ 87efc6a777Slinjiawei assert(in.aw.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 88efc6a777Slinjiawei } 89efc6a777Slinjiawei when(in.ar.fire()){ 90efc6a777Slinjiawei assert(in.ar.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 91efc6a777Slinjiawei } 92075891a7Slinjiawei 932195ebbdSYinan Xu val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4) 94075891a7Slinjiawei 952195ebbdSYinan Xu val state = RegInit(s_idle) 96075891a7Slinjiawei 97075891a7Slinjiawei switch(state){ 98075891a7Slinjiawei is(s_idle){ 99075891a7Slinjiawei when(in.ar.fire()){ 100075891a7Slinjiawei state := s_rdata 101075891a7Slinjiawei } 102075891a7Slinjiawei when(in.aw.fire()){ 103075891a7Slinjiawei state := s_wdata 104075891a7Slinjiawei } 105075891a7Slinjiawei } 106075891a7Slinjiawei is(s_rdata){ 107075891a7Slinjiawei when(in.r.fire() && in.r.bits.last){ 108075891a7Slinjiawei state := s_idle 109075891a7Slinjiawei } 110075891a7Slinjiawei } 111075891a7Slinjiawei is(s_wdata){ 112075891a7Slinjiawei when(in.w.fire() && in.w.bits.last){ 113075891a7Slinjiawei state := s_wresp 114075891a7Slinjiawei } 115075891a7Slinjiawei } 116075891a7Slinjiawei is(s_wresp){ 117075891a7Slinjiawei when(in.b.fire()){ 118075891a7Slinjiawei state := s_idle 119075891a7Slinjiawei } 120075891a7Slinjiawei } 121075891a7Slinjiawei } 122075891a7Slinjiawei 123075891a7Slinjiawei 1241db30e61Slinjiawei val fullMask = MaskExpand(in.w.bits.strb) 1251db30e61Slinjiawei 1261db30e61Slinjiawei def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask) 1271db30e61Slinjiawei 1281db30e61Slinjiawei val raddr = Wire(UInt()) 1291db30e61Slinjiawei val (readBeatCnt, rLast) = { 1301db30e61Slinjiawei val c = Counter(256) 1311db30e61Slinjiawei val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 132efc6a777Slinjiawei raddr := HoldUnless(in.ar.bits.addr, in.ar.fire()) 1331db30e61Slinjiawei in.r.bits.last := (c.value === len) 134efc6a777Slinjiawei 1351db30e61Slinjiawei when(in.r.fire()) { 1361db30e61Slinjiawei c.inc() 1371db30e61Slinjiawei when(in.r.bits.last) { 1381db30e61Slinjiawei c.value := 0.U 1391db30e61Slinjiawei } 1401db30e61Slinjiawei } 1411db30e61Slinjiawei when(in.ar.fire()) { 142efc6a777Slinjiawei assert( 143efc6a777Slinjiawei in.ar.bits.len === 0.U || 144efc6a777Slinjiawei in.ar.bits.len === 1.U || 145efc6a777Slinjiawei in.ar.bits.len === 3.U || 146efc6a777Slinjiawei in.ar.bits.len === 7.U || 147efc6a777Slinjiawei in.ar.bits.len === 15.U 148efc6a777Slinjiawei ) 1491db30e61Slinjiawei } 150efc6a777Slinjiawei (c.value, in.r.bits.last) 1511db30e61Slinjiawei } 1521db30e61Slinjiawei 153075891a7Slinjiawei in.ar.ready := state === s_idle 1541db30e61Slinjiawei in.r.bits.resp := AXI4Parameters.RESP_OKAY 155075891a7Slinjiawei in.r.valid := state === s_rdata 1561db30e61Slinjiawei 1571db30e61Slinjiawei 1581db30e61Slinjiawei val waddr = Wire(UInt()) 1591db30e61Slinjiawei val (writeBeatCnt, wLast) = { 1601db30e61Slinjiawei val c = Counter(256) 1611db30e61Slinjiawei waddr := HoldUnless(in.aw.bits.addr, in.aw.fire()) 1621db30e61Slinjiawei when(in.w.fire()) { 1631db30e61Slinjiawei c.inc() 1641db30e61Slinjiawei when(in.w.bits.last) { 1651db30e61Slinjiawei c.value := 0.U 1661db30e61Slinjiawei } 1671db30e61Slinjiawei } 1681db30e61Slinjiawei (c.value, in.w.bits.last) 1691db30e61Slinjiawei } 1701db30e61Slinjiawei 1716c6d537cSAllen in.aw.ready := state === s_idle && !in.ar.valid 172075891a7Slinjiawei in.w.ready := state === s_wdata 173075891a7Slinjiawei 1741db30e61Slinjiawei in.b.bits.resp := AXI4Parameters.RESP_OKAY 175075891a7Slinjiawei in.b.valid := state===s_wresp 1761db30e61Slinjiawei 1771db30e61Slinjiawei in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire()) 1781db30e61Slinjiawei in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire()) 1791db30e61Slinjiawei in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire()) 1801db30e61Slinjiawei in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire()) 1811db30e61Slinjiawei} 182