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