xref: /XiangShan/src/main/scala/device/AXI4DummySD.scala (revision 3c02ee8f82edea481fa8336c7f54ffc17fafba91)
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
174bf9a978SZihao Yupackage device
184bf9a978SZihao Yu
19956d83c0Slinjiaweiimport chipsalliance.rocketchip.config.Parameters
204bf9a978SZihao Yuimport chisel3._
21510ae4eeSJiuyang Liuimport chisel3.experimental.ExtModule
224bf9a978SZihao Yuimport chisel3.util._
23956d83c0Slinjiaweiimport freechips.rocketchip.diplomacy.AddressSet
24*3c02ee8fSwakafaimport utility._
254bf9a978SZihao Yu
264bf9a978SZihao Yutrait HasSDConst {
274bf9a978SZihao Yu  def MemorySize = 4L * 1024 * 1024 * 1024 // 4GB
284bf9a978SZihao Yu  def READ_BL_LEN = 15
29956d83c0Slinjiawei
304bf9a978SZihao Yu  def BlockLen = (1 << READ_BL_LEN)
31956d83c0Slinjiawei
324bf9a978SZihao Yu  def NrBlock = MemorySize / BlockLen
33956d83c0Slinjiawei
344bf9a978SZihao Yu  def C_SIZE_MULT = 7 // only 3 bits
354bf9a978SZihao Yu  def MULT = (1 << (C_SIZE_MULT + 2))
36956d83c0Slinjiawei
374bf9a978SZihao Yu  def C_SIZE = NrBlock / MULT - 1
384bf9a978SZihao Yu}
394bf9a978SZihao Yu
40510ae4eeSJiuyang Liuclass SDHelper extends ExtModule with HasExtModuleInline {
41510ae4eeSJiuyang Liu  val clk = IO(Input(Clock()))
42510ae4eeSJiuyang Liu  val ren = IO(Input(Bool()))
43510ae4eeSJiuyang Liu  val data = IO(Output(UInt(32.W)))
44510ae4eeSJiuyang Liu  val setAddr = IO(Input(Bool()))
45510ae4eeSJiuyang Liu  val addr = IO(Input(UInt(32.W)))
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)))
825dabf2dfSYinan Xu    val edmConst = (8 << 4).U(32.W) // 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)
124510ae4eeSJiuyang Liu    sdHelper.clk := clock
125510ae4eeSJiuyang Liu    sdHelper.ren := (getOffset(raddr) === 0x40.U && in.ar.fire())
126510ae4eeSJiuyang Liu    sdHelper.setAddr := setAddr
127510ae4eeSJiuyang Liu    sdHelper.addr := regs(sdarg)
128956d83c0Slinjiawei
129510ae4eeSJiuyang Liu    def sdRead = sdHelper.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))
1495dabf2dfSYinan Xu    val rdata = Wire(UInt(32.W))
1504bf9a978SZihao Yu    RegMap.generate(mapping, getOffset(raddr), rdata,
1515dabf2dfSYinan Xu      getOffset(waddr), in.w.fire(), in.w.bits.data(31, 0), MaskExpand(strb))
1524bf9a978SZihao Yu
1535dabf2dfSYinan Xu    in.r.bits.data := Fill(2, rdata)
1544bf9a978SZihao Yu  }
155956d83c0Slinjiawei}
156