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