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._ 22*3c02ee8fSwakafaimport utility._ 231db30e61Slinjiaweiimport freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, RegionType, TransferSizes} 241db30e61Slinjiaweiimport chipsalliance.rocketchip.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() 651db30e61Slinjiawei when(in.ar.fire()){ 66e2801f97Slinjiawei XSDebug(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 ) 701db30e61Slinjiawei } 711db30e61Slinjiawei when(in.aw.fire()){ 72e2801f97Slinjiawei XSDebug(p"[aw] addr: ${Hexadecimal(in.aw.bits.addr)} " + 731db30e61Slinjiawei p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " + 741db30e61Slinjiawei p"id: ${in.aw.bits.id}\n" 751db30e61Slinjiawei ) 761db30e61Slinjiawei } 771db30e61Slinjiawei when(in.w.fire()){ 7824b11ca3Slinjiawei XSDebug(p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n") 791db30e61Slinjiawei } 801db30e61Slinjiawei when(in.b.fire()){ 81e2801f97Slinjiawei XSDebug(p"[b] id: ${in.b.bits.id}\n") 821db30e61Slinjiawei } 831db30e61Slinjiawei when(in.r.fire()){ 8424b11ca3Slinjiawei XSDebug(p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n") 851db30e61Slinjiawei } 861db30e61Slinjiawei 87efc6a777Slinjiawei when(in.aw.fire()){ 88efc6a777Slinjiawei assert(in.aw.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 89efc6a777Slinjiawei } 90efc6a777Slinjiawei when(in.ar.fire()){ 91efc6a777Slinjiawei assert(in.ar.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 92efc6a777Slinjiawei } 93075891a7Slinjiawei 942195ebbdSYinan Xu val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4) 95075891a7Slinjiawei 962195ebbdSYinan Xu val state = RegInit(s_idle) 97075891a7Slinjiawei 98075891a7Slinjiawei switch(state){ 99075891a7Slinjiawei is(s_idle){ 100075891a7Slinjiawei when(in.ar.fire()){ 101075891a7Slinjiawei state := s_rdata 102075891a7Slinjiawei } 103075891a7Slinjiawei when(in.aw.fire()){ 104075891a7Slinjiawei state := s_wdata 105075891a7Slinjiawei } 106075891a7Slinjiawei } 107075891a7Slinjiawei is(s_rdata){ 108075891a7Slinjiawei when(in.r.fire() && in.r.bits.last){ 109075891a7Slinjiawei state := s_idle 110075891a7Slinjiawei } 111075891a7Slinjiawei } 112075891a7Slinjiawei is(s_wdata){ 113075891a7Slinjiawei when(in.w.fire() && in.w.bits.last){ 114075891a7Slinjiawei state := s_wresp 115075891a7Slinjiawei } 116075891a7Slinjiawei } 117075891a7Slinjiawei is(s_wresp){ 118075891a7Slinjiawei when(in.b.fire()){ 119075891a7Slinjiawei state := s_idle 120075891a7Slinjiawei } 121075891a7Slinjiawei } 122075891a7Slinjiawei } 123075891a7Slinjiawei 124075891a7Slinjiawei 1251db30e61Slinjiawei val fullMask = MaskExpand(in.w.bits.strb) 1261db30e61Slinjiawei 1271db30e61Slinjiawei def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask) 1281db30e61Slinjiawei 1291db30e61Slinjiawei val raddr = Wire(UInt()) 1301db30e61Slinjiawei val (readBeatCnt, rLast) = { 1311db30e61Slinjiawei val c = Counter(256) 1321db30e61Slinjiawei val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 133efc6a777Slinjiawei raddr := HoldUnless(in.ar.bits.addr, in.ar.fire()) 1341db30e61Slinjiawei in.r.bits.last := (c.value === len) 135efc6a777Slinjiawei 1361db30e61Slinjiawei when(in.r.fire()) { 1371db30e61Slinjiawei c.inc() 1381db30e61Slinjiawei when(in.r.bits.last) { 1391db30e61Slinjiawei c.value := 0.U 1401db30e61Slinjiawei } 1411db30e61Slinjiawei } 1421db30e61Slinjiawei when(in.ar.fire()) { 143efc6a777Slinjiawei assert( 144efc6a777Slinjiawei in.ar.bits.len === 0.U || 145efc6a777Slinjiawei in.ar.bits.len === 1.U || 146efc6a777Slinjiawei in.ar.bits.len === 3.U || 147efc6a777Slinjiawei in.ar.bits.len === 7.U || 148efc6a777Slinjiawei in.ar.bits.len === 15.U 149efc6a777Slinjiawei ) 1501db30e61Slinjiawei } 151efc6a777Slinjiawei (c.value, in.r.bits.last) 1521db30e61Slinjiawei } 1531db30e61Slinjiawei 154075891a7Slinjiawei in.ar.ready := state === s_idle 1551db30e61Slinjiawei in.r.bits.resp := AXI4Parameters.RESP_OKAY 156075891a7Slinjiawei in.r.valid := state === s_rdata 1571db30e61Slinjiawei 1581db30e61Slinjiawei 1591db30e61Slinjiawei val waddr = Wire(UInt()) 1601db30e61Slinjiawei val (writeBeatCnt, wLast) = { 1611db30e61Slinjiawei val c = Counter(256) 1621db30e61Slinjiawei waddr := HoldUnless(in.aw.bits.addr, in.aw.fire()) 1631db30e61Slinjiawei when(in.w.fire()) { 1641db30e61Slinjiawei c.inc() 1651db30e61Slinjiawei when(in.w.bits.last) { 1661db30e61Slinjiawei c.value := 0.U 1671db30e61Slinjiawei } 1681db30e61Slinjiawei } 1691db30e61Slinjiawei (c.value, in.w.bits.last) 1701db30e61Slinjiawei } 1711db30e61Slinjiawei 1726c6d537cSAllen in.aw.ready := state === s_idle && !in.ar.valid 173075891a7Slinjiawei in.w.ready := state === s_wdata 174075891a7Slinjiawei 1751db30e61Slinjiawei in.b.bits.resp := AXI4Parameters.RESP_OKAY 176075891a7Slinjiawei in.b.valid := state===s_wresp 1771db30e61Slinjiawei 1781db30e61Slinjiawei in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire()) 1791db30e61Slinjiawei in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire()) 1801db30e61Slinjiawei in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire()) 1811db30e61Slinjiawei in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire()) 1821db30e61Slinjiawei} 183