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