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