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