xref: /XiangShan/src/main/scala/device/AXI4DummySD.scala (revision 8891a219bbc84f568e1d134854d8d5ed86d6d560)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17package device
18
19import org.chipsalliance.cde.config.Parameters
20import chisel3._
21import chisel3.experimental.ExtModule
22import chisel3.util._
23import freechips.rocketchip.diplomacy.AddressSet
24import utility._
25
26trait HasSDConst {
27  def MemorySize = 4L * 1024 * 1024 * 1024 // 4GB
28  def READ_BL_LEN = 15
29
30  def BlockLen = (1 << READ_BL_LEN)
31
32  def NrBlock = MemorySize / BlockLen
33
34  def C_SIZE_MULT = 7 // only 3 bits
35  def MULT = (1 << (C_SIZE_MULT + 2))
36
37  def C_SIZE = NrBlock / MULT - 1
38}
39
40class SDHelper extends ExtModule with HasExtModuleInline {
41  val clk = IO(Input(Clock()))
42  val ren = IO(Input(Bool()))
43  val data = IO(Output(UInt(32.W)))
44  val setAddr = IO(Input(Bool()))
45  val addr = IO(Input(UInt(32.W)))
46
47  setInline("SDHelper.v",
48    s"""
49       |import "DPI-C" function void sd_setaddr(input int addr);
50       |import "DPI-C" function void sd_read(output int data);
51       |
52       |module SDHelper (
53       |  input clk,
54       |  input setAddr,
55       |  input [31:0] addr,
56       |  input ren,
57       |  output reg [31:0] data
58       |);
59       |
60       |  always @(negedge clk) begin
61       |    if (ren) sd_read(data);
62       |  end
63       |  always@(posedge clk) begin
64       |    if (setAddr) sd_setaddr(addr);
65       |  end
66       |
67       |endmodule
68     """.stripMargin)
69}
70
71class AXI4DummySD
72(
73  address: Seq[AddressSet]
74)(implicit p: Parameters)
75  extends AXI4SlaveModule(address, executable = false) with HasSDConst
76{
77  override lazy val module = new AXI4SlaveModuleImp[Null](this) {
78    val range = List.range(0, 21)
79    val sdcmd :: sdarg :: sdtout :: sdcdiv :: sdrsp0 :: sdrsp1 :: sdrsp2 :: sdrsp3 :: sdhsts :: __pad0 :: __pad1 :: __pad2 :: sdvdd :: sdedm :: sdhcfg :: sdhbct :: sddata :: __pad10 :: __pad11 :: __pad12 :: sdhblc :: Nil = range
80
81    val regs = List.fill(range.size)(RegInit(0.U(32.W)))
82    val edmConst = (8 << 4).U(32.W) // number of data in fifo
83
84    val MMC_SEND_OP_COND = 1
85    val MMC_ALL_SEND_CID = 2
86    val MMC_SEND_CSD = 9
87    val MMC_SEND_STATUS = 13
88    val MMC_READ_MULTIPLE_BLOCK = 18
89
90    val setAddr = WireInit(false.B)
91
92    def cmdWfn(wdata: UInt) = {
93      val cmd = wdata(5, 0)
94      switch(cmd) {
95        is(MMC_SEND_OP_COND.U) {
96          regs(sdrsp0) := "h80ff8000".U
97        }
98        is(MMC_ALL_SEND_CID.U) {
99          regs(sdrsp0) := "h00000001".U
100          regs(sdrsp1) := "h00000000".U
101          regs(sdrsp2) := "h00000000".U
102          regs(sdrsp3) := "h15000000".U
103        }
104        is(MMC_SEND_CSD.U) {
105          regs(sdrsp0) := "h92404001".U
106          regs(sdrsp1) := "h124b97e3".U | (C_SIZE.U(1, 0) << 30)
107          regs(sdrsp2) := "h0f508000".U | C_SIZE.U(11, 2) | (READ_BL_LEN.U << 16)
108          regs(sdrsp3) := "h8c26012a".U
109        }
110        is(MMC_SEND_STATUS.U) {
111          regs(sdrsp0) := 0.U
112          regs(sdrsp1) := 0.U
113          regs(sdrsp2) := 0.U
114          regs(sdrsp3) := 0.U
115        }
116        is(MMC_READ_MULTIPLE_BLOCK.U) {
117          setAddr := true.B
118        }
119      }
120      wdata
121    }
122
123    val sdHelper = Module(new SDHelper)
124    sdHelper.clk := clock
125    sdHelper.ren := (getOffset(raddr) === 0x40.U && in.ar.fire)
126    sdHelper.setAddr := setAddr
127    sdHelper.addr := regs(sdarg)
128
129    def sdRead = sdHelper.data
130
131    val mapping = Map(
132      RegMap(0x00, regs(sdcmd), cmdWfn),
133      RegMap(0x04, regs(sdarg)),
134      RegMap(0x10, regs(sdrsp0), RegMap.Unwritable),
135      RegMap(0x14, regs(sdrsp1), RegMap.Unwritable),
136      RegMap(0x18, regs(sdrsp2), RegMap.Unwritable),
137      RegMap(0x1c, regs(sdrsp3), RegMap.Unwritable),
138      RegMap(0x20, regs(sdhsts)),
139      RegMap(0x34, edmConst, RegMap.Unwritable),
140      RegMap(0x38, regs(sdhcfg)),
141      RegMap(0x38, regs(sdhbct)),
142      RegMap(0x40, sdRead, RegMap.Unwritable),
143      RegMap(0x50, regs(sdhblc))
144    )
145
146    def getOffset(addr: UInt) = addr(12, 0)
147
148    val strb = Mux(waddr(2), in.w.bits.strb(7, 4), in.w.bits.strb(3, 0))
149    val rdata = Wire(UInt(32.W))
150    RegMap.generate(mapping, getOffset(raddr), rdata,
151      getOffset(waddr), in.w.fire, in.w.bits.data(31, 0), MaskExpand(strb))
152
153    in.r.bits.data := Fill(2, rdata)
154  }
155}
156