1c6d43980SLemover/*************************************************************************************** 2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory 4c6d43980SLemover* 5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2. 6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at: 8c6d43980SLemover* http://license.coscl.org.cn/MulanPSL2 9c6d43980SLemover* 10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13c6d43980SLemover* 14c6d43980SLemover* See the Mulan PSL v2 for more details. 15c6d43980SLemover***************************************************************************************/ 16c6d43980SLemover 174bf9a978SZihao Yupackage device 184bf9a978SZihao Yu 19956d83c0Slinjiaweiimport chipsalliance.rocketchip.config.Parameters 204bf9a978SZihao Yuimport chisel3._ 21510ae4eeSJiuyang Liuimport chisel3.experimental.ExtModule 224bf9a978SZihao Yuimport chisel3.util._ 23956d83c0Slinjiaweiimport freechips.rocketchip.diplomacy.AddressSet 24*3c02ee8fSwakafaimport utility._ 254bf9a978SZihao Yu 264bf9a978SZihao Yutrait HasSDConst { 274bf9a978SZihao Yu def MemorySize = 4L * 1024 * 1024 * 1024 // 4GB 284bf9a978SZihao Yu def READ_BL_LEN = 15 29956d83c0Slinjiawei 304bf9a978SZihao Yu def BlockLen = (1 << READ_BL_LEN) 31956d83c0Slinjiawei 324bf9a978SZihao Yu def NrBlock = MemorySize / BlockLen 33956d83c0Slinjiawei 344bf9a978SZihao Yu def C_SIZE_MULT = 7 // only 3 bits 354bf9a978SZihao Yu def MULT = (1 << (C_SIZE_MULT + 2)) 36956d83c0Slinjiawei 374bf9a978SZihao Yu def C_SIZE = NrBlock / MULT - 1 384bf9a978SZihao Yu} 394bf9a978SZihao Yu 40510ae4eeSJiuyang Liuclass SDHelper extends ExtModule with HasExtModuleInline { 41510ae4eeSJiuyang Liu val clk = IO(Input(Clock())) 42510ae4eeSJiuyang Liu val ren = IO(Input(Bool())) 43510ae4eeSJiuyang Liu val data = IO(Output(UInt(32.W))) 44510ae4eeSJiuyang Liu val setAddr = IO(Input(Bool())) 45510ae4eeSJiuyang Liu val addr = IO(Input(UInt(32.W))) 464bf9a978SZihao Yu 474bf9a978SZihao Yu setInline("SDHelper.v", 484bf9a978SZihao Yu s""" 494bf9a978SZihao Yu |import "DPI-C" function void sd_setaddr(input int addr); 509f842a1aSYinan Xu |import "DPI-C" function void sd_read(output int data); 514bf9a978SZihao Yu | 524bf9a978SZihao Yu |module SDHelper ( 534bf9a978SZihao Yu | input clk, 544bf9a978SZihao Yu | input setAddr, 554bf9a978SZihao Yu | input [31:0] addr, 564bf9a978SZihao Yu | input ren, 579f842a1aSYinan Xu | output reg [31:0] data 584bf9a978SZihao Yu |); 594bf9a978SZihao Yu | 609f842a1aSYinan Xu | always @(negedge clk) begin 619f842a1aSYinan Xu | if (ren) sd_read(data); 629f842a1aSYinan Xu | end 63dc264b71SYinan Xu | always@(posedge clk) begin 649f842a1aSYinan Xu | if (setAddr) sd_setaddr(addr); 654bf9a978SZihao Yu | end 664bf9a978SZihao Yu | 674bf9a978SZihao Yu |endmodule 684bf9a978SZihao Yu """.stripMargin) 694bf9a978SZihao Yu} 704bf9a978SZihao Yu 71956d83c0Slinjiaweiclass AXI4DummySD 72956d83c0Slinjiawei( 73a2e9bde6SAllen address: Seq[AddressSet] 74956d83c0Slinjiawei)(implicit p: Parameters) 75956d83c0Slinjiawei extends AXI4SlaveModule(address, executable = false) with HasSDConst 76956d83c0Slinjiawei{ 77956d83c0Slinjiawei override lazy val module = new AXI4SlaveModuleImp[Null](this) { 784bf9a978SZihao Yu val range = List.range(0, 21) 794bf9a978SZihao Yu val sdcmd :: sdarg :: sdtout :: sdcdiv :: sdrsp0 :: sdrsp1 :: sdrsp2 :: sdrsp3 :: sdhsts :: __pad0 :: __pad1 :: __pad2 :: sdvdd :: sdedm :: sdhcfg :: sdhbct :: sddata :: __pad10 :: __pad11 :: __pad12 :: sdhblc :: Nil = range 804bf9a978SZihao Yu 814bf9a978SZihao Yu val regs = List.fill(range.size)(RegInit(0.U(32.W))) 825dabf2dfSYinan Xu val edmConst = (8 << 4).U(32.W) // number of data in fifo 834bf9a978SZihao Yu 844bf9a978SZihao Yu val MMC_SEND_OP_COND = 1 854bf9a978SZihao Yu val MMC_ALL_SEND_CID = 2 864bf9a978SZihao Yu val MMC_SEND_CSD = 9 874bf9a978SZihao Yu val MMC_SEND_STATUS = 13 884bf9a978SZihao Yu val MMC_READ_MULTIPLE_BLOCK = 18 894bf9a978SZihao Yu 904bf9a978SZihao Yu val setAddr = WireInit(false.B) 914bf9a978SZihao Yu 924bf9a978SZihao Yu def cmdWfn(wdata: UInt) = { 934bf9a978SZihao Yu val cmd = wdata(5, 0) 944bf9a978SZihao Yu switch(cmd) { 954bf9a978SZihao Yu is(MMC_SEND_OP_COND.U) { 964bf9a978SZihao Yu regs(sdrsp0) := "h80ff8000".U 974bf9a978SZihao Yu } 984bf9a978SZihao Yu is(MMC_ALL_SEND_CID.U) { 994bf9a978SZihao Yu regs(sdrsp0) := "h00000001".U 1004bf9a978SZihao Yu regs(sdrsp1) := "h00000000".U 1014bf9a978SZihao Yu regs(sdrsp2) := "h00000000".U 1024bf9a978SZihao Yu regs(sdrsp3) := "h15000000".U 1034bf9a978SZihao Yu } 1044bf9a978SZihao Yu is(MMC_SEND_CSD.U) { 1054bf9a978SZihao Yu regs(sdrsp0) := "h92404001".U 1064bf9a978SZihao Yu regs(sdrsp1) := "h124b97e3".U | (C_SIZE.U(1, 0) << 30) 1074bf9a978SZihao Yu regs(sdrsp2) := "h0f508000".U | C_SIZE.U(11, 2) | (READ_BL_LEN.U << 16) 1084bf9a978SZihao Yu regs(sdrsp3) := "h8c26012a".U 1094bf9a978SZihao Yu } 1104bf9a978SZihao Yu is(MMC_SEND_STATUS.U) { 1114bf9a978SZihao Yu regs(sdrsp0) := 0.U 1124bf9a978SZihao Yu regs(sdrsp1) := 0.U 1134bf9a978SZihao Yu regs(sdrsp2) := 0.U 1144bf9a978SZihao Yu regs(sdrsp3) := 0.U 1154bf9a978SZihao Yu } 1164bf9a978SZihao Yu is(MMC_READ_MULTIPLE_BLOCK.U) { 1174bf9a978SZihao Yu setAddr := true.B 1184bf9a978SZihao Yu } 1194bf9a978SZihao Yu } 1204bf9a978SZihao Yu wdata 1214bf9a978SZihao Yu } 1224bf9a978SZihao Yu 1234bf9a978SZihao Yu val sdHelper = Module(new SDHelper) 124510ae4eeSJiuyang Liu sdHelper.clk := clock 125510ae4eeSJiuyang Liu sdHelper.ren := (getOffset(raddr) === 0x40.U && in.ar.fire()) 126510ae4eeSJiuyang Liu sdHelper.setAddr := setAddr 127510ae4eeSJiuyang Liu sdHelper.addr := regs(sdarg) 128956d83c0Slinjiawei 129510ae4eeSJiuyang Liu def sdRead = sdHelper.data 1304bf9a978SZihao Yu 1314bf9a978SZihao Yu val mapping = Map( 1324bf9a978SZihao Yu RegMap(0x00, regs(sdcmd), cmdWfn), 1334bf9a978SZihao Yu RegMap(0x04, regs(sdarg)), 1344bf9a978SZihao Yu RegMap(0x10, regs(sdrsp0), RegMap.Unwritable), 1354bf9a978SZihao Yu RegMap(0x14, regs(sdrsp1), RegMap.Unwritable), 1364bf9a978SZihao Yu RegMap(0x18, regs(sdrsp2), RegMap.Unwritable), 1374bf9a978SZihao Yu RegMap(0x1c, regs(sdrsp3), RegMap.Unwritable), 1384bf9a978SZihao Yu RegMap(0x20, regs(sdhsts)), 1394bf9a978SZihao Yu RegMap(0x34, edmConst, RegMap.Unwritable), 1404bf9a978SZihao Yu RegMap(0x38, regs(sdhcfg)), 1414bf9a978SZihao Yu RegMap(0x38, regs(sdhbct)), 1424bf9a978SZihao Yu RegMap(0x40, sdRead, RegMap.Unwritable), 1434bf9a978SZihao Yu RegMap(0x50, regs(sdhblc)) 1444bf9a978SZihao Yu ) 145956d83c0Slinjiawei 1464bf9a978SZihao Yu def getOffset(addr: UInt) = addr(12, 0) 1474bf9a978SZihao Yu 1484bf9a978SZihao Yu val strb = Mux(waddr(2), in.w.bits.strb(7, 4), in.w.bits.strb(3, 0)) 1495dabf2dfSYinan Xu val rdata = Wire(UInt(32.W)) 1504bf9a978SZihao Yu RegMap.generate(mapping, getOffset(raddr), rdata, 1515dabf2dfSYinan Xu getOffset(waddr), in.w.fire(), in.w.bits.data(31, 0), MaskExpand(strb)) 1524bf9a978SZihao Yu 1535dabf2dfSYinan Xu in.r.bits.data := Fill(2, rdata) 1544bf9a978SZihao Yu } 155956d83c0Slinjiawei} 156