xref: /XiangShan/src/main/scala/device/AXI4DummySD.scala (revision f320e0f01bd645f0a3045a8a740e60dd770734a9)
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
174bf9a978SZihao Yupackage device
184bf9a978SZihao Yu
19956d83c0Slinjiaweiimport chipsalliance.rocketchip.config.Parameters
204bf9a978SZihao Yuimport chisel3._
214bf9a978SZihao Yuimport chisel3.util._
22956d83c0Slinjiaweiimport freechips.rocketchip.diplomacy.AddressSet
234bf9a978SZihao Yuimport utils._
244bf9a978SZihao Yu
254bf9a978SZihao Yutrait HasSDConst {
264bf9a978SZihao Yu  def MemorySize = 4L * 1024 * 1024 * 1024 // 4GB
274bf9a978SZihao Yu  def READ_BL_LEN = 15
28956d83c0Slinjiawei
294bf9a978SZihao Yu  def BlockLen = (1 << READ_BL_LEN)
30956d83c0Slinjiawei
314bf9a978SZihao Yu  def NrBlock = MemorySize / BlockLen
32956d83c0Slinjiawei
334bf9a978SZihao Yu  def C_SIZE_MULT = 7 // only 3 bits
344bf9a978SZihao Yu  def MULT = (1 << (C_SIZE_MULT + 2))
35956d83c0Slinjiawei
364bf9a978SZihao Yu  def C_SIZE = NrBlock / MULT - 1
374bf9a978SZihao Yu}
384bf9a978SZihao Yu
394bf9a978SZihao Yuclass SDHelper extends BlackBox with HasBlackBoxInline {
404bf9a978SZihao Yu  val io = IO(new Bundle {
414bf9a978SZihao Yu    val clk = Input(Clock())
424bf9a978SZihao Yu    val ren = Input(Bool())
434bf9a978SZihao Yu    val data = Output(UInt(32.W))
444bf9a978SZihao Yu    val setAddr = Input(Bool())
454bf9a978SZihao Yu    val addr = Input(UInt(32.W))
464bf9a978SZihao Yu  })
474bf9a978SZihao Yu
484bf9a978SZihao Yu  setInline("SDHelper.v",
494bf9a978SZihao Yu    s"""
504bf9a978SZihao Yu       |import "DPI-C" function void sd_setaddr(input int addr);
519f842a1aSYinan Xu       |import "DPI-C" function void sd_read(output int data);
524bf9a978SZihao Yu       |
534bf9a978SZihao Yu       |module SDHelper (
544bf9a978SZihao Yu       |  input clk,
554bf9a978SZihao Yu       |  input setAddr,
564bf9a978SZihao Yu       |  input [31:0] addr,
574bf9a978SZihao Yu       |  input ren,
589f842a1aSYinan Xu       |  output reg [31:0] data
594bf9a978SZihao Yu       |);
604bf9a978SZihao Yu       |
619f842a1aSYinan Xu       |  always @(negedge clk) begin
629f842a1aSYinan Xu       |    if (ren) sd_read(data);
639f842a1aSYinan Xu       |  end
64dc264b71SYinan Xu       |  always@(posedge clk) begin
659f842a1aSYinan Xu       |    if (setAddr) sd_setaddr(addr);
664bf9a978SZihao Yu       |  end
674bf9a978SZihao Yu       |
684bf9a978SZihao Yu       |endmodule
694bf9a978SZihao Yu     """.stripMargin)
704bf9a978SZihao Yu}
714bf9a978SZihao Yu
72956d83c0Slinjiaweiclass AXI4DummySD
73956d83c0Slinjiawei(
74a2e9bde6SAllen  address: Seq[AddressSet]
75956d83c0Slinjiawei)(implicit p: Parameters)
76956d83c0Slinjiawei  extends AXI4SlaveModule(address, executable = false) with HasSDConst
77956d83c0Slinjiawei{
78956d83c0Slinjiawei  override lazy val module = new AXI4SlaveModuleImp[Null](this) {
794bf9a978SZihao Yu    val range = List.range(0, 21)
804bf9a978SZihao 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
814bf9a978SZihao Yu
824bf9a978SZihao Yu    val regs = List.fill(range.size)(RegInit(0.U(32.W)))
834bf9a978SZihao Yu    val edmConst = (8 << 4).U // number of data in fifo
844bf9a978SZihao Yu
854bf9a978SZihao Yu    val MMC_SEND_OP_COND = 1
864bf9a978SZihao Yu    val MMC_ALL_SEND_CID = 2
874bf9a978SZihao Yu    val MMC_SEND_CSD = 9
884bf9a978SZihao Yu    val MMC_SEND_STATUS = 13
894bf9a978SZihao Yu    val MMC_READ_MULTIPLE_BLOCK = 18
904bf9a978SZihao Yu
914bf9a978SZihao Yu    val setAddr = WireInit(false.B)
924bf9a978SZihao Yu
934bf9a978SZihao Yu    def cmdWfn(wdata: UInt) = {
944bf9a978SZihao Yu      val cmd = wdata(5, 0)
954bf9a978SZihao Yu      switch(cmd) {
964bf9a978SZihao Yu        is(MMC_SEND_OP_COND.U) {
974bf9a978SZihao Yu          regs(sdrsp0) := "h80ff8000".U
984bf9a978SZihao Yu        }
994bf9a978SZihao Yu        is(MMC_ALL_SEND_CID.U) {
1004bf9a978SZihao Yu          regs(sdrsp0) := "h00000001".U
1014bf9a978SZihao Yu          regs(sdrsp1) := "h00000000".U
1024bf9a978SZihao Yu          regs(sdrsp2) := "h00000000".U
1034bf9a978SZihao Yu          regs(sdrsp3) := "h15000000".U
1044bf9a978SZihao Yu        }
1054bf9a978SZihao Yu        is(MMC_SEND_CSD.U) {
1064bf9a978SZihao Yu          regs(sdrsp0) := "h92404001".U
1074bf9a978SZihao Yu          regs(sdrsp1) := "h124b97e3".U | (C_SIZE.U(1, 0) << 30)
1084bf9a978SZihao Yu          regs(sdrsp2) := "h0f508000".U | C_SIZE.U(11, 2) | (READ_BL_LEN.U << 16)
1094bf9a978SZihao Yu          regs(sdrsp3) := "h8c26012a".U
1104bf9a978SZihao Yu        }
1114bf9a978SZihao Yu        is(MMC_SEND_STATUS.U) {
1124bf9a978SZihao Yu          regs(sdrsp0) := 0.U
1134bf9a978SZihao Yu          regs(sdrsp1) := 0.U
1144bf9a978SZihao Yu          regs(sdrsp2) := 0.U
1154bf9a978SZihao Yu          regs(sdrsp3) := 0.U
1164bf9a978SZihao Yu        }
1174bf9a978SZihao Yu        is(MMC_READ_MULTIPLE_BLOCK.U) {
1184bf9a978SZihao Yu          setAddr := true.B
1194bf9a978SZihao Yu        }
1204bf9a978SZihao Yu      }
1214bf9a978SZihao Yu      wdata
1224bf9a978SZihao Yu    }
1234bf9a978SZihao Yu
1244bf9a978SZihao Yu    val sdHelper = Module(new SDHelper)
1254bf9a978SZihao Yu    sdHelper.io.clk := clock
126956d83c0Slinjiawei    sdHelper.io.ren := (getOffset(raddr) === 0x40.U && in.ar.fire())
1274bf9a978SZihao Yu    sdHelper.io.setAddr := setAddr
1284bf9a978SZihao Yu    sdHelper.io.addr := regs(sdarg)
129956d83c0Slinjiawei
1304bf9a978SZihao Yu    def sdRead = sdHelper.io.data
1314bf9a978SZihao Yu
1324bf9a978SZihao Yu    val mapping = Map(
1334bf9a978SZihao Yu      RegMap(0x00, regs(sdcmd), cmdWfn),
1344bf9a978SZihao Yu      RegMap(0x04, regs(sdarg)),
1354bf9a978SZihao Yu      RegMap(0x10, regs(sdrsp0), RegMap.Unwritable),
1364bf9a978SZihao Yu      RegMap(0x14, regs(sdrsp1), RegMap.Unwritable),
1374bf9a978SZihao Yu      RegMap(0x18, regs(sdrsp2), RegMap.Unwritable),
1384bf9a978SZihao Yu      RegMap(0x1c, regs(sdrsp3), RegMap.Unwritable),
1394bf9a978SZihao Yu      RegMap(0x20, regs(sdhsts)),
1404bf9a978SZihao Yu      RegMap(0x34, edmConst, RegMap.Unwritable),
1414bf9a978SZihao Yu      RegMap(0x38, regs(sdhcfg)),
1424bf9a978SZihao Yu      RegMap(0x38, regs(sdhbct)),
1434bf9a978SZihao Yu      RegMap(0x40, sdRead, RegMap.Unwritable),
1444bf9a978SZihao Yu      RegMap(0x50, regs(sdhblc))
1454bf9a978SZihao Yu    )
146956d83c0Slinjiawei
1474bf9a978SZihao Yu    def getOffset(addr: UInt) = addr(12, 0)
1484bf9a978SZihao Yu
1494bf9a978SZihao Yu    val strb = Mux(waddr(2), in.w.bits.strb(7, 4), in.w.bits.strb(3, 0))
1504bf9a978SZihao Yu    val rdata = Wire(UInt(64.W))
1514bf9a978SZihao Yu    RegMap.generate(mapping, getOffset(raddr), rdata,
1524bf9a978SZihao Yu      getOffset(waddr), in.w.fire(), in.w.bits.data, MaskExpand(strb))
1534bf9a978SZihao Yu
154efc6a777Slinjiawei    in.r.bits.data := Fill(2, rdata(31, 0))
1554bf9a978SZihao Yu  }
156956d83c0Slinjiawei}
157