14bf9a978SZihao Yupackage device 24bf9a978SZihao Yu 3956d83c0Slinjiaweiimport chipsalliance.rocketchip.config.Parameters 44bf9a978SZihao Yuimport chisel3._ 54bf9a978SZihao Yuimport chisel3.util._ 6956d83c0Slinjiaweiimport freechips.rocketchip.diplomacy.AddressSet 74bf9a978SZihao Yuimport utils._ 84bf9a978SZihao Yu 94bf9a978SZihao Yutrait HasSDConst { 104bf9a978SZihao Yu def MemorySize = 4L * 1024 * 1024 * 1024 // 4GB 114bf9a978SZihao Yu def READ_BL_LEN = 15 12956d83c0Slinjiawei 134bf9a978SZihao Yu def BlockLen = (1 << READ_BL_LEN) 14956d83c0Slinjiawei 154bf9a978SZihao Yu def NrBlock = MemorySize / BlockLen 16956d83c0Slinjiawei 174bf9a978SZihao Yu def C_SIZE_MULT = 7 // only 3 bits 184bf9a978SZihao Yu def MULT = (1 << (C_SIZE_MULT + 2)) 19956d83c0Slinjiawei 204bf9a978SZihao Yu def C_SIZE = NrBlock / MULT - 1 214bf9a978SZihao Yu} 224bf9a978SZihao Yu 234bf9a978SZihao Yuclass SDHelper extends BlackBox with HasBlackBoxInline { 244bf9a978SZihao Yu val io = IO(new Bundle { 254bf9a978SZihao Yu val clk = Input(Clock()) 264bf9a978SZihao Yu val ren = Input(Bool()) 274bf9a978SZihao Yu val data = Output(UInt(32.W)) 284bf9a978SZihao Yu val setAddr = Input(Bool()) 294bf9a978SZihao Yu val addr = Input(UInt(32.W)) 304bf9a978SZihao Yu }) 314bf9a978SZihao Yu 324bf9a978SZihao Yu setInline("SDHelper.v", 334bf9a978SZihao Yu s""" 344bf9a978SZihao Yu |import "DPI-C" function void sd_setaddr(input int addr); 35*dc264b71SYinan Xu |import "DPI-C" function int sd_read(input bit ren); 364bf9a978SZihao Yu | 374bf9a978SZihao Yu |module SDHelper ( 384bf9a978SZihao Yu | input clk, 394bf9a978SZihao Yu | input setAddr, 404bf9a978SZihao Yu | input [31:0] addr, 414bf9a978SZihao Yu | input ren, 42*dc264b71SYinan Xu | output [31:0] data 434bf9a978SZihao Yu |); 444bf9a978SZihao Yu | 45*dc264b71SYinan Xu | always @(posedge clk) begin 46*dc264b71SYinan Xu | if (setAddr) begin 47*dc264b71SYinan Xu | sd_setaddr(addr); 484bf9a978SZihao Yu | end 49*dc264b71SYinan Xu | end 50*dc264b71SYinan Xu | 51*dc264b71SYinan Xu | assign data = sd_read(ren); 524bf9a978SZihao Yu | 534bf9a978SZihao Yu |endmodule 544bf9a978SZihao Yu """.stripMargin) 554bf9a978SZihao Yu} 564bf9a978SZihao Yu 57956d83c0Slinjiaweiclass AXI4DummySD 58956d83c0Slinjiawei( 59a2e9bde6SAllen address: Seq[AddressSet] 60956d83c0Slinjiawei)(implicit p: Parameters) 61956d83c0Slinjiawei extends AXI4SlaveModule(address, executable = false) with HasSDConst 62956d83c0Slinjiawei{ 63956d83c0Slinjiawei override lazy val module = new AXI4SlaveModuleImp[Null](this) { 644bf9a978SZihao Yu val range = List.range(0, 21) 654bf9a978SZihao 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 664bf9a978SZihao Yu 674bf9a978SZihao Yu val regs = List.fill(range.size)(RegInit(0.U(32.W))) 684bf9a978SZihao Yu val edmConst = (8 << 4).U // number of data in fifo 694bf9a978SZihao Yu 704bf9a978SZihao Yu val MMC_SEND_OP_COND = 1 714bf9a978SZihao Yu val MMC_ALL_SEND_CID = 2 724bf9a978SZihao Yu val MMC_SEND_CSD = 9 734bf9a978SZihao Yu val MMC_SEND_STATUS = 13 744bf9a978SZihao Yu val MMC_READ_MULTIPLE_BLOCK = 18 754bf9a978SZihao Yu 764bf9a978SZihao Yu val setAddr = WireInit(false.B) 774bf9a978SZihao Yu 784bf9a978SZihao Yu def cmdWfn(wdata: UInt) = { 794bf9a978SZihao Yu val cmd = wdata(5, 0) 804bf9a978SZihao Yu switch(cmd) { 814bf9a978SZihao Yu is(MMC_SEND_OP_COND.U) { 824bf9a978SZihao Yu regs(sdrsp0) := "h80ff8000".U 834bf9a978SZihao Yu } 844bf9a978SZihao Yu is(MMC_ALL_SEND_CID.U) { 854bf9a978SZihao Yu regs(sdrsp0) := "h00000001".U 864bf9a978SZihao Yu regs(sdrsp1) := "h00000000".U 874bf9a978SZihao Yu regs(sdrsp2) := "h00000000".U 884bf9a978SZihao Yu regs(sdrsp3) := "h15000000".U 894bf9a978SZihao Yu } 904bf9a978SZihao Yu is(MMC_SEND_CSD.U) { 914bf9a978SZihao Yu regs(sdrsp0) := "h92404001".U 924bf9a978SZihao Yu regs(sdrsp1) := "h124b97e3".U | (C_SIZE.U(1, 0) << 30) 934bf9a978SZihao Yu regs(sdrsp2) := "h0f508000".U | C_SIZE.U(11, 2) | (READ_BL_LEN.U << 16) 944bf9a978SZihao Yu regs(sdrsp3) := "h8c26012a".U 954bf9a978SZihao Yu } 964bf9a978SZihao Yu is(MMC_SEND_STATUS.U) { 974bf9a978SZihao Yu regs(sdrsp0) := 0.U 984bf9a978SZihao Yu regs(sdrsp1) := 0.U 994bf9a978SZihao Yu regs(sdrsp2) := 0.U 1004bf9a978SZihao Yu regs(sdrsp3) := 0.U 1014bf9a978SZihao Yu } 1024bf9a978SZihao Yu is(MMC_READ_MULTIPLE_BLOCK.U) { 1034bf9a978SZihao Yu setAddr := true.B 1044bf9a978SZihao Yu } 1054bf9a978SZihao Yu } 1064bf9a978SZihao Yu wdata 1074bf9a978SZihao Yu } 1084bf9a978SZihao Yu 1094bf9a978SZihao Yu val sdHelper = Module(new SDHelper) 1104bf9a978SZihao Yu sdHelper.io.clk := clock 111956d83c0Slinjiawei sdHelper.io.ren := (getOffset(raddr) === 0x40.U && in.ar.fire()) 1124bf9a978SZihao Yu sdHelper.io.setAddr := setAddr 1134bf9a978SZihao Yu sdHelper.io.addr := regs(sdarg) 114956d83c0Slinjiawei 1154bf9a978SZihao Yu def sdRead = sdHelper.io.data 1164bf9a978SZihao Yu 1174bf9a978SZihao Yu val mapping = Map( 1184bf9a978SZihao Yu RegMap(0x00, regs(sdcmd), cmdWfn), 1194bf9a978SZihao Yu RegMap(0x04, regs(sdarg)), 1204bf9a978SZihao Yu RegMap(0x10, regs(sdrsp0), RegMap.Unwritable), 1214bf9a978SZihao Yu RegMap(0x14, regs(sdrsp1), RegMap.Unwritable), 1224bf9a978SZihao Yu RegMap(0x18, regs(sdrsp2), RegMap.Unwritable), 1234bf9a978SZihao Yu RegMap(0x1c, regs(sdrsp3), RegMap.Unwritable), 1244bf9a978SZihao Yu RegMap(0x20, regs(sdhsts)), 1254bf9a978SZihao Yu RegMap(0x34, edmConst, RegMap.Unwritable), 1264bf9a978SZihao Yu RegMap(0x38, regs(sdhcfg)), 1274bf9a978SZihao Yu RegMap(0x38, regs(sdhbct)), 1284bf9a978SZihao Yu RegMap(0x40, sdRead, RegMap.Unwritable), 1294bf9a978SZihao Yu RegMap(0x50, regs(sdhblc)) 1304bf9a978SZihao Yu ) 131956d83c0Slinjiawei 1324bf9a978SZihao Yu def getOffset(addr: UInt) = addr(12, 0) 1334bf9a978SZihao Yu 1344bf9a978SZihao Yu val strb = Mux(waddr(2), in.w.bits.strb(7, 4), in.w.bits.strb(3, 0)) 1354bf9a978SZihao Yu val rdata = Wire(UInt(64.W)) 1364bf9a978SZihao Yu RegMap.generate(mapping, getOffset(raddr), rdata, 1374bf9a978SZihao Yu getOffset(waddr), in.w.fire(), in.w.bits.data, MaskExpand(strb)) 1384bf9a978SZihao Yu 139efc6a777Slinjiawei in.r.bits.data := Fill(2, rdata(31, 0)) 1404bf9a978SZihao Yu } 141956d83c0Slinjiawei} 142