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