xref: /XiangShan/src/main/scala/device/AXI4DummySD.scala (revision c6d439803a044ea209139672b25e35fe8d7f4aa0)
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
164bf9a978SZihao Yupackage device
174bf9a978SZihao Yu
18956d83c0Slinjiaweiimport chipsalliance.rocketchip.config.Parameters
194bf9a978SZihao Yuimport chisel3._
204bf9a978SZihao Yuimport chisel3.util._
21956d83c0Slinjiaweiimport freechips.rocketchip.diplomacy.AddressSet
224bf9a978SZihao Yuimport utils._
234bf9a978SZihao Yu
244bf9a978SZihao Yutrait HasSDConst {
254bf9a978SZihao Yu  def MemorySize = 4L * 1024 * 1024 * 1024 // 4GB
264bf9a978SZihao Yu  def READ_BL_LEN = 15
27956d83c0Slinjiawei
284bf9a978SZihao Yu  def BlockLen = (1 << READ_BL_LEN)
29956d83c0Slinjiawei
304bf9a978SZihao Yu  def NrBlock = MemorySize / BlockLen
31956d83c0Slinjiawei
324bf9a978SZihao Yu  def C_SIZE_MULT = 7 // only 3 bits
334bf9a978SZihao Yu  def MULT = (1 << (C_SIZE_MULT + 2))
34956d83c0Slinjiawei
354bf9a978SZihao Yu  def C_SIZE = NrBlock / MULT - 1
364bf9a978SZihao Yu}
374bf9a978SZihao Yu
384bf9a978SZihao Yuclass SDHelper extends BlackBox with HasBlackBoxInline {
394bf9a978SZihao Yu  val io = IO(new Bundle {
404bf9a978SZihao Yu    val clk = Input(Clock())
414bf9a978SZihao Yu    val ren = Input(Bool())
424bf9a978SZihao Yu    val data = Output(UInt(32.W))
434bf9a978SZihao Yu    val setAddr = Input(Bool())
444bf9a978SZihao Yu    val addr = Input(UInt(32.W))
454bf9a978SZihao Yu  })
464bf9a978SZihao Yu
474bf9a978SZihao Yu  setInline("SDHelper.v",
484bf9a978SZihao Yu    s"""
494bf9a978SZihao Yu       |import "DPI-C" function void sd_setaddr(input int addr);
509f842a1aSYinan Xu       |import "DPI-C" function void sd_read(output int data);
514bf9a978SZihao Yu       |
524bf9a978SZihao Yu       |module SDHelper (
534bf9a978SZihao Yu       |  input clk,
544bf9a978SZihao Yu       |  input setAddr,
554bf9a978SZihao Yu       |  input [31:0] addr,
564bf9a978SZihao Yu       |  input ren,
579f842a1aSYinan Xu       |  output reg [31:0] data
584bf9a978SZihao Yu       |);
594bf9a978SZihao Yu       |
609f842a1aSYinan Xu       |  always @(negedge clk) begin
619f842a1aSYinan Xu       |    if (ren) sd_read(data);
629f842a1aSYinan Xu       |  end
63dc264b71SYinan Xu       |  always@(posedge clk) begin
649f842a1aSYinan Xu       |    if (setAddr) sd_setaddr(addr);
654bf9a978SZihao Yu       |  end
664bf9a978SZihao Yu       |
674bf9a978SZihao Yu       |endmodule
684bf9a978SZihao Yu     """.stripMargin)
694bf9a978SZihao Yu}
704bf9a978SZihao Yu
71956d83c0Slinjiaweiclass AXI4DummySD
72956d83c0Slinjiawei(
73a2e9bde6SAllen  address: Seq[AddressSet]
74956d83c0Slinjiawei)(implicit p: Parameters)
75956d83c0Slinjiawei  extends AXI4SlaveModule(address, executable = false) with HasSDConst
76956d83c0Slinjiawei{
77956d83c0Slinjiawei  override lazy val module = new AXI4SlaveModuleImp[Null](this) {
784bf9a978SZihao Yu    val range = List.range(0, 21)
794bf9a978SZihao Yu    val sdcmd :: sdarg :: sdtout :: sdcdiv :: sdrsp0 :: sdrsp1 :: sdrsp2 :: sdrsp3 :: sdhsts :: __pad0 :: __pad1 :: __pad2 :: sdvdd :: sdedm :: sdhcfg :: sdhbct :: sddata :: __pad10 :: __pad11 :: __pad12 :: sdhblc :: Nil = range
804bf9a978SZihao Yu
814bf9a978SZihao Yu    val regs = List.fill(range.size)(RegInit(0.U(32.W)))
824bf9a978SZihao Yu    val edmConst = (8 << 4).U // number of data in fifo
834bf9a978SZihao Yu
844bf9a978SZihao Yu    val MMC_SEND_OP_COND = 1
854bf9a978SZihao Yu    val MMC_ALL_SEND_CID = 2
864bf9a978SZihao Yu    val MMC_SEND_CSD = 9
874bf9a978SZihao Yu    val MMC_SEND_STATUS = 13
884bf9a978SZihao Yu    val MMC_READ_MULTIPLE_BLOCK = 18
894bf9a978SZihao Yu
904bf9a978SZihao Yu    val setAddr = WireInit(false.B)
914bf9a978SZihao Yu
924bf9a978SZihao Yu    def cmdWfn(wdata: UInt) = {
934bf9a978SZihao Yu      val cmd = wdata(5, 0)
944bf9a978SZihao Yu      switch(cmd) {
954bf9a978SZihao Yu        is(MMC_SEND_OP_COND.U) {
964bf9a978SZihao Yu          regs(sdrsp0) := "h80ff8000".U
974bf9a978SZihao Yu        }
984bf9a978SZihao Yu        is(MMC_ALL_SEND_CID.U) {
994bf9a978SZihao Yu          regs(sdrsp0) := "h00000001".U
1004bf9a978SZihao Yu          regs(sdrsp1) := "h00000000".U
1014bf9a978SZihao Yu          regs(sdrsp2) := "h00000000".U
1024bf9a978SZihao Yu          regs(sdrsp3) := "h15000000".U
1034bf9a978SZihao Yu        }
1044bf9a978SZihao Yu        is(MMC_SEND_CSD.U) {
1054bf9a978SZihao Yu          regs(sdrsp0) := "h92404001".U
1064bf9a978SZihao Yu          regs(sdrsp1) := "h124b97e3".U | (C_SIZE.U(1, 0) << 30)
1074bf9a978SZihao Yu          regs(sdrsp2) := "h0f508000".U | C_SIZE.U(11, 2) | (READ_BL_LEN.U << 16)
1084bf9a978SZihao Yu          regs(sdrsp3) := "h8c26012a".U
1094bf9a978SZihao Yu        }
1104bf9a978SZihao Yu        is(MMC_SEND_STATUS.U) {
1114bf9a978SZihao Yu          regs(sdrsp0) := 0.U
1124bf9a978SZihao Yu          regs(sdrsp1) := 0.U
1134bf9a978SZihao Yu          regs(sdrsp2) := 0.U
1144bf9a978SZihao Yu          regs(sdrsp3) := 0.U
1154bf9a978SZihao Yu        }
1164bf9a978SZihao Yu        is(MMC_READ_MULTIPLE_BLOCK.U) {
1174bf9a978SZihao Yu          setAddr := true.B
1184bf9a978SZihao Yu        }
1194bf9a978SZihao Yu      }
1204bf9a978SZihao Yu      wdata
1214bf9a978SZihao Yu    }
1224bf9a978SZihao Yu
1234bf9a978SZihao Yu    val sdHelper = Module(new SDHelper)
1244bf9a978SZihao Yu    sdHelper.io.clk := clock
125956d83c0Slinjiawei    sdHelper.io.ren := (getOffset(raddr) === 0x40.U && in.ar.fire())
1264bf9a978SZihao Yu    sdHelper.io.setAddr := setAddr
1274bf9a978SZihao Yu    sdHelper.io.addr := regs(sdarg)
128956d83c0Slinjiawei
1294bf9a978SZihao Yu    def sdRead = sdHelper.io.data
1304bf9a978SZihao Yu
1314bf9a978SZihao Yu    val mapping = Map(
1324bf9a978SZihao Yu      RegMap(0x00, regs(sdcmd), cmdWfn),
1334bf9a978SZihao Yu      RegMap(0x04, regs(sdarg)),
1344bf9a978SZihao Yu      RegMap(0x10, regs(sdrsp0), RegMap.Unwritable),
1354bf9a978SZihao Yu      RegMap(0x14, regs(sdrsp1), RegMap.Unwritable),
1364bf9a978SZihao Yu      RegMap(0x18, regs(sdrsp2), RegMap.Unwritable),
1374bf9a978SZihao Yu      RegMap(0x1c, regs(sdrsp3), RegMap.Unwritable),
1384bf9a978SZihao Yu      RegMap(0x20, regs(sdhsts)),
1394bf9a978SZihao Yu      RegMap(0x34, edmConst, RegMap.Unwritable),
1404bf9a978SZihao Yu      RegMap(0x38, regs(sdhcfg)),
1414bf9a978SZihao Yu      RegMap(0x38, regs(sdhbct)),
1424bf9a978SZihao Yu      RegMap(0x40, sdRead, RegMap.Unwritable),
1434bf9a978SZihao Yu      RegMap(0x50, regs(sdhblc))
1444bf9a978SZihao Yu    )
145956d83c0Slinjiawei
1464bf9a978SZihao Yu    def getOffset(addr: UInt) = addr(12, 0)
1474bf9a978SZihao Yu
1484bf9a978SZihao Yu    val strb = Mux(waddr(2), in.w.bits.strb(7, 4), in.w.bits.strb(3, 0))
1494bf9a978SZihao Yu    val rdata = Wire(UInt(64.W))
1504bf9a978SZihao Yu    RegMap.generate(mapping, getOffset(raddr), rdata,
1514bf9a978SZihao Yu      getOffset(waddr), in.w.fire(), in.w.bits.data, MaskExpand(strb))
1524bf9a978SZihao Yu
153efc6a777Slinjiawei    in.r.bits.data := Fill(2, rdata(31, 0))
1544bf9a978SZihao Yu  }
155956d83c0Slinjiawei}
156