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