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