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