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