--- /dev/null
+# This file is Copyright (c) 2018 Florent Kermarrec <florent@enjoy-digital.fr>
+# License: BSD
+
+from litex.build.generic_platform import *
+from litex.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer
+
+_io = [
+ ("user_led", 0, Pins("H17"), IOStandard("LVCMOS33")),
+ ("user_led", 1, Pins("K15"), IOStandard("LVCMOS33")),
+ ("user_led", 2, Pins("J13"), IOStandard("LVCMOS33")),
+ ("user_led", 3, Pins("N14"), IOStandard("LVCMOS33")),
+ ("user_led", 4, Pins("R18"), IOStandard("LVCMOS33")),
+ ("user_led", 5, Pins("V17"), IOStandard("LVCMOS33")),
+ ("user_led", 6, Pins("U17"), IOStandard("LVCMOS33")),
+ ("user_led", 7, Pins("U16"), IOStandard("LVCMOS33")),
+ ("user_led", 8, Pins("V16"), IOStandard("LVCMOS33")),
+ ("user_led", 9, Pins("T15"), IOStandard("LVCMOS33")),
+ ("user_led", 10, Pins("U14"), IOStandard("LVCMOS33")),
+ ("user_led", 11, Pins("T16"), IOStandard("LVCMOS33")),
+ ("user_led", 12, Pins("V15"), IOStandard("LVCMOS33")),
+ ("user_led", 13, Pins("V14"), IOStandard("LVCMOS33")),
+ ("user_led", 14, Pins("V12"), IOStandard("LVCMOS33")),
+ ("user_led", 15, Pins("V11"), IOStandard("LVCMOS33")),
+
+ ("clk100", 0, Pins("E3"), IOStandard("LVCMOS33")),
+
+ ("cpu_reset", 0, Pins("C12"), IOStandard("LVCMOS33")),
+
+ ("serial", 0,
+ Subsignal("tx", Pins("D4")),
+ Subsignal("rx", Pins("C4")),
+ IOStandard("LVCMOS33"),
+ ),
+
+ ("ddram", 0,
+ Subsignal("a", Pins(
+ "M4 P4 M6 T1 L3 P5 M2 N1",
+ "L4 N5 R2 K5 N6"),
+ IOStandard("SSTL18_II")),
+ Subsignal("ba", Pins("P2 P3 R1"), IOStandard("SSTL18_II")),
+ Subsignal("ras_n", Pins("N4"), IOStandard("SSTL18_II")),
+ Subsignal("cas_n", Pins("L3"), IOStandard("SSTL18_II")),
+ Subsignal("we_n", Pins("N2"), IOStandard("SSTL18_II")),
+ Subsignal("dm", Pins("T6 U1"), IOStandard("SSTL18_II")),
+ Subsignal("dq", Pins(
+ "R7 V6 R8 U7 V7 R6 U6 R5",
+ "T5 U3 V5 U4 V4 T4 V1 T3"),
+ IOStandard("SSTL18_II"),
+ Misc("IN_TERM=UNTUNED_SPLIT_50")),
+ Subsignal("dqs_p", Pins("U9 U2"), IOStandard("DIFF_SSTL18_II")),
+ Subsignal("dqs_n", Pins("V9 V2"), IOStandard("DIFF_SSTL18_II")),
+ Subsignal("clk_p", Pins("L6"), IOStandard("DIFF_SSTL18_II")),
+ Subsignal("clk_n", Pins("L5"), IOStandard("DIFF_SSTL18_II")),
+ Subsignal("cke", Pins("M1"), IOStandard("SSTL18_II")),
+ Subsignal("odt", Pins("M3"), IOStandard("SSTL18_II")),
+ Subsignal("cs_n", Pins("K6"), IOStandard("SSTL18_II")),
+ Misc("SLEW=FAST"),
+ ),
+]
+
+
+class Platform(XilinxPlatform):
+ default_clk_name = "clk100"
+ default_clk_period = 10.0
+
+ def __init__(self, programmer="vivado"):
+ XilinxPlatform.__init__(self, "xc7a100t-CSG324-1", _io, toolchain="vivado")
+ self.programmer = programmer
+ self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 35]")
+
+
+ def create_programmer(self):
+ if self.programmer == "xc3sprog":
+ return XC3SProg("nexys4")
+ elif self.programmer == "vivado":
+ return VivadoProgrammer()
+ else:
+ raise ValueError("{} programmer is not supported"
+ .format(self.programmer))
+
+ def do_finalize(self, fragment):
+ XilinxPlatform.do_finalize(self, fragment)
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+
+from litex.gen import *
+from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+
+from litex.boards.platforms import nexys4ddr
+
+from litex.soc.integration.soc_core import mem_decoder
+from litex.soc.integration.soc_sdram import *
+from litex.soc.integration.builder import *
+
+from litedram.modules import MT41K256M16
+from litedram.phy import a7ddrphy
+
+
+class _CRG(Module):
+ def __init__(self, platform):
+ self.clock_domains.cd_sys = ClockDomain()
+ self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
+ self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
+ self.clock_domains.cd_clk200 = ClockDomain()
+ self.clock_domains.cd_clk100 = ClockDomain()
+
+ clk100 = platform.request("clk100")
+ rst = ~platform.request("cpu_reset")
+
+ pll_locked = Signal()
+ pll_fb = Signal()
+ self.pll_sys = Signal()
+ pll_sys4x = Signal()
+ pll_sys4x_dqs = Signal()
+ pll_clk200 = 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=self.pll_sys,
+
+ # 400 MHz
+ p_CLKOUT1_DIVIDE=4, p_CLKOUT1_PHASE=0.0,
+ o_CLKOUT1=pll_sys4x,
+
+ # 400 MHz dqs
+ p_CLKOUT2_DIVIDE=4, p_CLKOUT2_PHASE=90.0,
+ o_CLKOUT2=pll_sys4x_dqs,
+
+ # 200 MHz
+ p_CLKOUT3_DIVIDE=8, p_CLKOUT3_PHASE=0.0,
+ o_CLKOUT3=pll_clk200
+ ),
+ Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk),
+ Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk),
+ Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk),
+ Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk),
+ Instance("BUFG", i_I=clk100, o_O=self.cd_clk100.clk),
+ AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst),
+ AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst),
+ AsyncResetSynchronizer(self.cd_clk100, ~pll_locked | rst),
+ ]
+
+ reset_counter = Signal(4, reset=15)
+ ic_reset = Signal(reset=1)
+ self.sync.clk200 += \
+ If(reset_counter != 0,
+ reset_counter.eq(reset_counter - 1)
+ ).Else(
+ ic_reset.eq(0)
+ )
+ self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset)
+
+
+class BaseSoC(SoCSDRAM):
+ csr_map = {
+ "ddrphy": 16,
+ }
+ csr_map.update(SoCSDRAM.csr_map)
+ def __init__(self, **kwargs):
+ platform = nexys4ddr.Platform()
+ SoCSDRAM.__init__(self, platform, clk_freq=100*1000000,
+ integrated_rom_size=0x8000,
+ integrated_sram_size=0x8000,
+ **kwargs)
+
+ self.submodules.crg = _CRG(platform)
+
+ # sdram
+ self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram"))
+ self.add_constant("READ_LEVELING_BITSLIP", 3)
+ self.add_constant("READ_LEVELING_DELAY", 14)
+ sdram_module = MT41K256M16(self.clk_freq, "1:4")
+ self.register_sdram(self.ddrphy,
+ sdram_module.geom_settings,
+ sdram_module.timing_settings)
+
+
+def main():
+ parser = argparse.ArgumentParser(description="LiteX SoC port to Nexys4DDR")
+ builder_args(parser)
+ soc_sdram_args(parser)
+ args = parser.parse_args()
+
+ soc = BaseSoC(**soc_sdram_argdict(args))
+ builder = Builder(soc, **builder_argdict(args))
+ builder.build()
+
+
+if __name__ == "__main__":
+ main()