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