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