Skip to content

Instantly share code, notes, and snippets.

@olofk
Last active August 20, 2019 12:25
Show Gist options
  • Select an option

  • Save olofk/f121e9c0acdae17bb3167d3d75f81a31 to your computer and use it in GitHub Desktop.

Select an option

Save olofk/f121e9c0acdae17bb3167d3d75f81a31 to your computer and use it in GitHub Desktop.
import sys
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.build.generic_platform import Subsignal, Pins, Misc, IOStandard
from litex.soc.cores.timer import Timer
from litex.soc.interconnect.csr import Module, ClockDomain, Signal, Instance
from litex.soc.interconnect.wishbone import CSRBank
from litesdcard.phy import SDPHY
from litesdcard.clocker import SDClockerS7
from litesdcard.core import SDCore
from litex.boards.platforms import nexys4ddr
_sd_io = [
("sdcard", 0,
Subsignal("data", Pins("V11 T13 U13 U12"), Misc("PULLUP True")),
Subsignal("cmd", Pins("V10"), Misc("PULLUP True")),
Subsignal("clk", Pins("V12")),
IOStandard("LVCMOS33"), Misc("SLEW=FAST")
),
("sink", 0,
Subsignal("valid", Pins(1)),
Subsignal("ready", Pins(1)),
Subsignal("first", Pins(1)),
Subsignal("last", Pins(1)),
Subsignal("payload", Pins(32)),
),
("source", 0,
Subsignal("valid", Pins(1)),
Subsignal("ready", Pins(1)),
Subsignal("first", Pins(1)),
Subsignal("last", Pins(1)),
Subsignal("payload", Pins(32)),
),
("wb", 0,
Subsignal("adr", Pins(30)),
Subsignal("dat_w", Pins(32)),
Subsignal("sel", Pins(4)),
Subsignal("we", Pins(1)),
Subsignal("cyc", Pins(1)),
Subsignal("stb", Pins(1)),
Subsignal("cti", Pins(3)),
Subsignal("bte", Pins(2)),
Subsignal("dat_r", Pins(32)),
Subsignal("ack", Pins(1)),
Subsignal("err", Pins(1)),
),
]
class _CRG(Module):
def __init__(self, platform):
self.clock_domains.cd_sys = ClockDomain()
# # #
clk100 = platform.request("clk100")
rst = ~platform.request("cpu_reset")
pll_locked = Signal()
pll_fb = Signal()
pll_sys = Signal()
self.specials += [
Instance("PLLE2_BASE",
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
# VCO @ 1600 MHz
p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0,
p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1,
i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb,
# 100 MHz
p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0,
o_CLKOUT0=pll_sys
),
Instance("BUFG", i_I=pll_sys, o_O=self.cd_sys.clk),
AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst),
]
class SDTop(Module):
def __init__(self):
platform = nexys4ddr.Platform()
platform.add_extension(_sd_io)
clk_freq = int(100e6)
sd_freq = int(100e6)
self.clk_freq = clk_freq
self.sd_freq = sd_freq
self.submodules.crg = _CRG(platform)
sdcard_pads = platform.request('sdcard')
# sd
self.submodules.sdclk = SDClockerS7()
self.submodules.sdphy = SDPHY(sdcard_pads, platform.device)
self.submodules.sdcore = SDCore(self.sdphy)
self.submodules.sdtimer = Timer()
csrs = self.sdcore.get_csrs()
for csr in csrs:
print(csr.name)
print(dir(csrs[0]))
self.submodules.csr_bank = CSRBank(csrs)
platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq)
platform.add_period_constraint(self.sdclk.cd_sd.clk, 1e9/sd_freq)
platform.add_period_constraint(self.sdclk.cd_sd_fb.clk, 1e9/sd_freq)
self.crg.cd_sys.clk.attr.add("keep")
self.sdclk.cd_sd.clk.attr.add("keep")
self.sdclk.cd_sd_fb.clk.attr.add("keep")
platform.add_false_path_constraints(
self.crg.cd_sys.clk,
self.sdclk.cd_sd.clk,
self.sdclk.cd_sd_fb.clk)
sink_pads = platform.request("sink")
self.comb += [
self.sdcore.sink.valid.eq(sink_pads.valid),
sink_pads.ready.eq(self.sdcore.sink.ready),
self.sdcore.sink.first.eq(sink_pads.first),
self.sdcore.sink.last.eq(sink_pads.last),
self.sdcore.sink.payload.eq(sink_pads.payload),
]
source_pads = platform.request("source")
self.comb += [
source_pads.valid.eq( self.sdcore.source.valid),
self.sdcore.source.ready.eq( source_pads.ready),
source_pads.first.eq( self.sdcore.source.first),
source_pads.last.eq( self.sdcore.source.last),
source_pads.payload.eq(self.sdcore.source.payload.data),
]
wb_pads = platform.request("wb")
self.comb += [
self.csr_bank.bus.adr.eq( wb_pads.adr),
self.csr_bank.bus.dat_w.eq(wb_pads.dat_w),
self.csr_bank.bus.sel.eq( wb_pads.sel),
self.csr_bank.bus.we.eq( wb_pads.we),
self.csr_bank.bus.cyc.eq( wb_pads.cyc),
self.csr_bank.bus.stb.eq( wb_pads.stb),
self.csr_bank.bus.cti.eq( wb_pads.cti),
self.csr_bank.bus.bte.eq( wb_pads.bte),
wb_pads.dat_r.eq(self.csr_bank.bus.dat_r),
wb_pads.ack.eq( self.csr_bank.bus.ack),
wb_pads.err.eq( self.csr_bank.bus.err),
]
self.platform = platform
def main():
args = sys.argv[1:]
soc = SDTop()
frag = soc.get_fragment()
soc.platform.get_verilog(frag).write("sd.v")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment