1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package device 18 19import chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import freechips.rocketchip.diplomacy.AddressSet 23import utils._ 24 25trait HasSDConst { 26 def MemorySize = 4L * 1024 * 1024 * 1024 // 4GB 27 def READ_BL_LEN = 15 28 29 def BlockLen = (1 << READ_BL_LEN) 30 31 def NrBlock = MemorySize / BlockLen 32 33 def C_SIZE_MULT = 7 // only 3 bits 34 def MULT = (1 << (C_SIZE_MULT + 2)) 35 36 def C_SIZE = NrBlock / MULT - 1 37} 38 39class SDHelper extends BlackBox with HasBlackBoxInline { 40 val io = IO(new Bundle { 41 val clk = Input(Clock()) 42 val ren = Input(Bool()) 43 val data = Output(UInt(32.W)) 44 val setAddr = Input(Bool()) 45 val addr = Input(UInt(32.W)) 46 }) 47 48 setInline("SDHelper.v", 49 s""" 50 |import "DPI-C" function void sd_setaddr(input int addr); 51 |import "DPI-C" function void sd_read(output int data); 52 | 53 |module SDHelper ( 54 | input clk, 55 | input setAddr, 56 | input [31:0] addr, 57 | input ren, 58 | output reg [31:0] data 59 |); 60 | 61 | always @(negedge clk) begin 62 | if (ren) sd_read(data); 63 | end 64 | always@(posedge clk) begin 65 | if (setAddr) sd_setaddr(addr); 66 | end 67 | 68 |endmodule 69 """.stripMargin) 70} 71 72class AXI4DummySD 73( 74 address: Seq[AddressSet] 75)(implicit p: Parameters) 76 extends AXI4SlaveModule(address, executable = false) with HasSDConst 77{ 78 override lazy val module = new AXI4SlaveModuleImp[Null](this) { 79 val range = List.range(0, 21) 80 val sdcmd :: sdarg :: sdtout :: sdcdiv :: sdrsp0 :: sdrsp1 :: sdrsp2 :: sdrsp3 :: sdhsts :: __pad0 :: __pad1 :: __pad2 :: sdvdd :: sdedm :: sdhcfg :: sdhbct :: sddata :: __pad10 :: __pad11 :: __pad12 :: sdhblc :: Nil = range 81 82 val regs = List.fill(range.size)(RegInit(0.U(32.W))) 83 val edmConst = (8 << 4).U // number of data in fifo 84 85 val MMC_SEND_OP_COND = 1 86 val MMC_ALL_SEND_CID = 2 87 val MMC_SEND_CSD = 9 88 val MMC_SEND_STATUS = 13 89 val MMC_READ_MULTIPLE_BLOCK = 18 90 91 val setAddr = WireInit(false.B) 92 93 def cmdWfn(wdata: UInt) = { 94 val cmd = wdata(5, 0) 95 switch(cmd) { 96 is(MMC_SEND_OP_COND.U) { 97 regs(sdrsp0) := "h80ff8000".U 98 } 99 is(MMC_ALL_SEND_CID.U) { 100 regs(sdrsp0) := "h00000001".U 101 regs(sdrsp1) := "h00000000".U 102 regs(sdrsp2) := "h00000000".U 103 regs(sdrsp3) := "h15000000".U 104 } 105 is(MMC_SEND_CSD.U) { 106 regs(sdrsp0) := "h92404001".U 107 regs(sdrsp1) := "h124b97e3".U | (C_SIZE.U(1, 0) << 30) 108 regs(sdrsp2) := "h0f508000".U | C_SIZE.U(11, 2) | (READ_BL_LEN.U << 16) 109 regs(sdrsp3) := "h8c26012a".U 110 } 111 is(MMC_SEND_STATUS.U) { 112 regs(sdrsp0) := 0.U 113 regs(sdrsp1) := 0.U 114 regs(sdrsp2) := 0.U 115 regs(sdrsp3) := 0.U 116 } 117 is(MMC_READ_MULTIPLE_BLOCK.U) { 118 setAddr := true.B 119 } 120 } 121 wdata 122 } 123 124 val sdHelper = Module(new SDHelper) 125 sdHelper.io.clk := clock 126 sdHelper.io.ren := (getOffset(raddr) === 0x40.U && in.ar.fire()) 127 sdHelper.io.setAddr := setAddr 128 sdHelper.io.addr := regs(sdarg) 129 130 def sdRead = sdHelper.io.data 131 132 val mapping = Map( 133 RegMap(0x00, regs(sdcmd), cmdWfn), 134 RegMap(0x04, regs(sdarg)), 135 RegMap(0x10, regs(sdrsp0), RegMap.Unwritable), 136 RegMap(0x14, regs(sdrsp1), RegMap.Unwritable), 137 RegMap(0x18, regs(sdrsp2), RegMap.Unwritable), 138 RegMap(0x1c, regs(sdrsp3), RegMap.Unwritable), 139 RegMap(0x20, regs(sdhsts)), 140 RegMap(0x34, edmConst, RegMap.Unwritable), 141 RegMap(0x38, regs(sdhcfg)), 142 RegMap(0x38, regs(sdhbct)), 143 RegMap(0x40, sdRead, RegMap.Unwritable), 144 RegMap(0x50, regs(sdhblc)) 145 ) 146 147 def getOffset(addr: UInt) = addr(12, 0) 148 149 val strb = Mux(waddr(2), in.w.bits.strb(7, 4), in.w.bits.strb(3, 0)) 150 val rdata = Wire(UInt(64.W)) 151 RegMap.generate(mapping, getOffset(raddr), rdata, 152 getOffset(waddr), in.w.fire(), in.w.bits.data, MaskExpand(strb)) 153 154 in.r.bits.data := Fill(2, rdata(31, 0)) 155 } 156} 157