xref: /XiangShan/src/main/scala/device/AXI4DummySD.scala (revision f320e0f01bd645f0a3045a8a740e60dd770734a9)
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 chipsalliance.rocketchip.config.Parameters
20import chisel3._
21import chisel3.util._
22import freechips.rocketchip.diplomacy.AddressSet
23import utils._
24
25trait HasSDConst {
26  def MemorySize = 4L * 1024 * 1024 * 1024 // 4GB
27  def READ_BL_LEN = 15
28
29  def BlockLen = (1 << READ_BL_LEN)
30
31  def NrBlock = MemorySize / BlockLen
32
33  def C_SIZE_MULT = 7 // only 3 bits
34  def MULT = (1 << (C_SIZE_MULT + 2))
35
36  def C_SIZE = NrBlock / MULT - 1
37}
38
39class SDHelper extends BlackBox with HasBlackBoxInline {
40  val io = IO(new Bundle {
41    val clk = Input(Clock())
42    val ren = Input(Bool())
43    val data = Output(UInt(32.W))
44    val setAddr = Input(Bool())
45    val addr = Input(UInt(32.W))
46  })
47
48  setInline("SDHelper.v",
49    s"""
50       |import "DPI-C" function void sd_setaddr(input int addr);
51       |import "DPI-C" function void sd_read(output int data);
52       |
53       |module SDHelper (
54       |  input clk,
55       |  input setAddr,
56       |  input [31:0] addr,
57       |  input ren,
58       |  output reg [31:0] data
59       |);
60       |
61       |  always @(negedge clk) begin
62       |    if (ren) sd_read(data);
63       |  end
64       |  always@(posedge clk) begin
65       |    if (setAddr) sd_setaddr(addr);
66       |  end
67       |
68       |endmodule
69     """.stripMargin)
70}
71
72class AXI4DummySD
73(
74  address: Seq[AddressSet]
75)(implicit p: Parameters)
76  extends AXI4SlaveModule(address, executable = false) with HasSDConst
77{
78  override lazy val module = new AXI4SlaveModuleImp[Null](this) {
79    val range = List.range(0, 21)
80    val sdcmd :: sdarg :: sdtout :: sdcdiv :: sdrsp0 :: sdrsp1 :: sdrsp2 :: sdrsp3 :: sdhsts :: __pad0 :: __pad1 :: __pad2 :: sdvdd :: sdedm :: sdhcfg :: sdhbct :: sddata :: __pad10 :: __pad11 :: __pad12 :: sdhblc :: Nil = range
81
82    val regs = List.fill(range.size)(RegInit(0.U(32.W)))
83    val edmConst = (8 << 4).U // number of data in fifo
84
85    val MMC_SEND_OP_COND = 1
86    val MMC_ALL_SEND_CID = 2
87    val MMC_SEND_CSD = 9
88    val MMC_SEND_STATUS = 13
89    val MMC_READ_MULTIPLE_BLOCK = 18
90
91    val setAddr = WireInit(false.B)
92
93    def cmdWfn(wdata: UInt) = {
94      val cmd = wdata(5, 0)
95      switch(cmd) {
96        is(MMC_SEND_OP_COND.U) {
97          regs(sdrsp0) := "h80ff8000".U
98        }
99        is(MMC_ALL_SEND_CID.U) {
100          regs(sdrsp0) := "h00000001".U
101          regs(sdrsp1) := "h00000000".U
102          regs(sdrsp2) := "h00000000".U
103          regs(sdrsp3) := "h15000000".U
104        }
105        is(MMC_SEND_CSD.U) {
106          regs(sdrsp0) := "h92404001".U
107          regs(sdrsp1) := "h124b97e3".U | (C_SIZE.U(1, 0) << 30)
108          regs(sdrsp2) := "h0f508000".U | C_SIZE.U(11, 2) | (READ_BL_LEN.U << 16)
109          regs(sdrsp3) := "h8c26012a".U
110        }
111        is(MMC_SEND_STATUS.U) {
112          regs(sdrsp0) := 0.U
113          regs(sdrsp1) := 0.U
114          regs(sdrsp2) := 0.U
115          regs(sdrsp3) := 0.U
116        }
117        is(MMC_READ_MULTIPLE_BLOCK.U) {
118          setAddr := true.B
119        }
120      }
121      wdata
122    }
123
124    val sdHelper = Module(new SDHelper)
125    sdHelper.io.clk := clock
126    sdHelper.io.ren := (getOffset(raddr) === 0x40.U && in.ar.fire())
127    sdHelper.io.setAddr := setAddr
128    sdHelper.io.addr := regs(sdarg)
129
130    def sdRead = sdHelper.io.data
131
132    val mapping = Map(
133      RegMap(0x00, regs(sdcmd), cmdWfn),
134      RegMap(0x04, regs(sdarg)),
135      RegMap(0x10, regs(sdrsp0), RegMap.Unwritable),
136      RegMap(0x14, regs(sdrsp1), RegMap.Unwritable),
137      RegMap(0x18, regs(sdrsp2), RegMap.Unwritable),
138      RegMap(0x1c, regs(sdrsp3), RegMap.Unwritable),
139      RegMap(0x20, regs(sdhsts)),
140      RegMap(0x34, edmConst, RegMap.Unwritable),
141      RegMap(0x38, regs(sdhcfg)),
142      RegMap(0x38, regs(sdhbct)),
143      RegMap(0x40, sdRead, RegMap.Unwritable),
144      RegMap(0x50, regs(sdhblc))
145    )
146
147    def getOffset(addr: UInt) = addr(12, 0)
148
149    val strb = Mux(waddr(2), in.w.bits.strb(7, 4), in.w.bits.strb(3, 0))
150    val rdata = Wire(UInt(64.W))
151    RegMap.generate(mapping, getOffset(raddr), rdata,
152      getOffset(waddr), in.w.fire(), in.w.bits.data, MaskExpand(strb))
153
154    in.r.bits.data := Fill(2, rdata(31, 0))
155  }
156}
157