# SDCARD0: 6 pins
("sdcard", 0,
Subsignal("clk", Pins("J1")),
- Subsignal("cmd", Pins("J3"), Misc("PULLMODE=UP")),
- Subsignal("data", Pins("K2 K1 H2 H1"), Misc("PULLMODE=UP")),
+ Subsignal("cmd_i", Pins("J3"), Misc("PULLMODE=UP")),
+ Subsignal("cmd_o", Pins("J3"), Misc("PULLMODE=UP")),
+ Subsignal("cmd_oe", Pins("J3"), Misc("PULLMODE=UP")),
+ Subsignal("data_i", Pins("K2 K1 H2 H1"), Misc("PULLMODE=UP")),
+ Subsignal("data_o", Pins("K2 K1 H2 H1"), Misc("PULLMODE=UP")),
+ Subsignal("data_oe", Pins("K2 K1 H2 H1"), Misc("PULLMODE=UP")),
Misc("SLEWRATE=FAST"),
IOStandard("LVCMOS33"),
),
pins = ' '.join(pins)
# 16 GPIOs
-#_io.append( ("gpio", 0,
-# Subsignal("target", Pins(pins), Misc("PULLMODE=UP")),
-# IOStandard("LVCMOS33")) )
-#_io.append( ("gpio", n_gpio, Pins(pins), IOStandard("LVCMOS33")) )
_io.append( ("gpio", 0,
Subsignal("i", Pins(pins), Misc("PULLMODE=UP")),
Subsignal("o", Pins(pins), Misc("PULLMODE=UP")),
Subsignal("oe", Pins(pins), Misc("PULLMODE=UP")),
IOStandard("LVCMOS33")) )
-#_io.append( ("gpio", n_gpio, Pins(pins), IOStandard("LVCMOS33")) )
# EINT: 3 pins
_io.append( ("eint", 3, Pins("E0 E1 E2"), IOStandard("LVCMOS33")) )
import os
import argparse
+from functools import reduce
+from operator import or_
from migen import (Signal, FSM, If, Display, Finish, NextValue, NextState,
- Record)
+ Record, ClockSignal, wrap)
from litex.build.generic_platform import Pins, Subsignal
from litex.build.sim import SimPlatform
from litex.soc.interconnect.csr import CSRStorage, CSRStatus
from migen.genlib.cdc import MultiReg
+# Imports
+from litex.soc.interconnect import wishbone
+from litesdcard.phy import (SDPHY, SDPHYClocker,
+ SDPHYInit, SDPHYCMDW, SDPHYCMDR,
+ SDPHYDATAW, SDPHYDATAR,
+ _sdpads_layout)
+from litesdcard.core import SDCore
+from litesdcard.frontend.dma import SDBlock2MemDMA, SDMem2BlockDMA
+from litex.build.io import SDROutput, SDRInput
+
class GPIOTristateASIC(Module, AutoCSR):
def __init__(self, pads):
for i in range(nbits):
self.specials += MultiReg(_pads.i[i], self._in.status[i])
+# SDCard PHY IO -------------------------------------------------------
+
+class SDRPad(Module):
+ def __init__(self, pad, name, sdpad):
+ clk = ClockSignal()
+ _o = getattr(pad, "%s_o" % name)
+ _oe = getattr(pad, "%s_oe" % name)
+ _i = getattr(pad, "%s_i" % name)
+ for j in range(len(_o)):
+ self.specials += SDROutput(clk=clk, i=sdpad.o[j], o=_o[j])
+ self.specials += SDROutput(clk=clk, i=sdpad.oe, o=_oe[j])
+ self.specials += SDRInput(clk=clk, i=_i[j], o=sdpad.i[j])
+
+
+class SDPHYIOGen(Module):
+ def __init__(self, clocker, sdpads, pads):
+ # Rst
+ if hasattr(pads, "rst"):
+ self.comb += pads.rst.eq(0)
+
+ # Clk
+ self.specials += SDROutput(
+ clk = ClockSignal(),
+ i = ~clocker.clk & sdpads.clk,
+ o = pads.clk
+ )
+
+ # Cmd
+ self.submodules.sd_cmd = SDRPad(pads, "cmd", sdpads.cmd)
+
+ # Data
+ self.submodules.sd_data = SDRPad(pads, "data", sdpads.data)
+
+
+class SDPHY(Module, AutoCSR):
+ def __init__(self, pads, device, sys_clk_freq,
+ cmd_timeout=10e-3, data_timeout=10e-3):
+ self.card_detect = CSRStatus() # Assume SDCard is present if no cd pin.
+ self.comb += self.card_detect.status.eq(getattr(pads, "cd", 0))
+
+ self.submodules.clocker = clocker = SDPHYClocker()
+ self.submodules.init = init = SDPHYInit()
+ self.submodules.cmdw = cmdw = SDPHYCMDW()
+ self.submodules.cmdr = cmdr = SDPHYCMDR(sys_clk_freq,
+ cmd_timeout, cmdw)
+ self.submodules.dataw = dataw = SDPHYDATAW()
+ self.submodules.datar = datar = SDPHYDATAR(sys_clk_freq,
+ data_timeout)
+
+ # # #
+
+ self.sdpads = sdpads = Record(_sdpads_layout)
+
+ # IOs
+ sdphy_cls = SDPHYIOGen
+ self.submodules.io = sdphy_cls(clocker, sdpads, pads)
+
+ # Connect pads_out of submodules to physical pads --------------
+ pl = [init, cmdw, cmdr, dataw, datar]
+ self.comb += [
+ sdpads.clk.eq( reduce(or_, [m.pads_out.clk for m in pl])),
+ sdpads.cmd.oe.eq( reduce(or_, [m.pads_out.cmd.oe for m in pl])),
+ sdpads.cmd.o.eq( reduce(or_, [m.pads_out.cmd.o for m in pl])),
+ sdpads.data.oe.eq(reduce(or_, [m.pads_out.data.oe for m in pl])),
+ sdpads.data.o.eq( reduce(or_, [m.pads_out.data.o for m in pl])),
+ ]
+ for m in pl:
+ self.comb += m.pads_out.ready.eq(self.clocker.ce)
-# LibreSoCSim -----------------------------------------------------------------
+ # Connect physical pads to pads_in of submodules ---------------
+ for m in pl:
+ self.comb += m.pads_in.valid.eq(self.clocker.ce)
+ self.comb += m.pads_in.cmd.i.eq(sdpads.cmd.i)
+ self.comb += m.pads_in.data.i.eq(sdpads.data.i)
+
+
+ # Speed Throttling -------------------------------------------
+ self.comb += clocker.stop.eq(dataw.stop | datar.stop)
+
+# LibreSoCSim -----------------------------------------------------------
class LibreSoCSim(SoCCore):
def __init__(self, cpu="libresoc", debug=False, with_sdram=True,
memtype = sdram_module.memtype,
data_width = sdram_data_width,
clk_freq = sdram_clk_freq)
- #sdrphy_cls = HalfRateGENSDRPHY
+ #sdrphy_cls = HalfRateGENSDRPHY
sdrphy_cls = GENSDRPHY
self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"))
#self.submodules.sdrphy = sdrphy_cls(sdram_module,
self.submodules.i2c = I2CMaster(platform.request("i2c"))
self.add_csr("i2c")
+ # SDCard -----------------------------------------------------
+
+ # Emulator / Pads
+ sdcard_pads = self.platform.request("sdcard")
+
+ # Core
+ self.submodules.sdphy = SDPHY(sdcard_pads,
+ self.platform.device, self.clk_freq)
+ self.submodules.sdcore = SDCore(self.sdphy)
+ self.add_csr("sdphy")
+ self.add_csr("sdcore")
+
+ # Block2Mem DMA
+ bus = wishbone.Interface(data_width=self.bus.data_width,
+ adr_width=self.bus.address_width)
+ self.submodules.sdblock2mem = SDBlock2MemDMA(bus=bus,
+ endianness=self.cpu.endianness)
+ self.comb += self.sdcore.source.connect(self.sdblock2mem.sink)
+ dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
+ dma_bus.add_master("sdblock2mem", master=bus)
+ self.add_csr("sdblock2mem")
+
+ # Mem2Block DMA
+ bus = wishbone.Interface(data_width=self.bus.data_width,
+ adr_width=self.bus.address_width)
+ self.submodules.sdmem2block = SDMem2BlockDMA(bus=bus,
+ endianness=self.cpu.endianness)
+ self.comb += self.sdmem2block.source.connect(self.sdcore.sink)
+ dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
+ dma_bus.add_master("sdmem2block", master=bus)
+ self.add_csr("sdmem2block")
+
# Debug ---------------------------------------------------------------
if not debug:
return
if args.platform == 'ls180':
soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
platform=args.platform)
- soc.add_sdcard()
soc.add_spi_sdcard()
builder = Builder(soc, compile_gateware = True)
builder.build(run = True)