diff --git a/litex_boards/platforms/zcu104.py b/litex_boards/platforms/zcu104.py new file mode 100644 index 0000000000..3c243a9aa2 --- /dev/null +++ b/litex_boards/platforms/zcu104.py @@ -0,0 +1,100 @@ +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform, VivadoProgrammer + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + ("clk125", 0, + Subsignal("p", Pins("F23"), IOStandard("LVDS")), + Subsignal("n", Pins("E23"), IOStandard("LVDS")), + ), + + ("clk300", 0, + Subsignal("p", Pins("AH18"), IOStandard("DIFF_SSTL12_DCI")), + Subsignal("n", Pins("AH17"), IOStandard("DIFF_SSTL12_DCI")), + ), + + ("user_led", 0, Pins("D5"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("D6"), IOStandard("LVCMOS33")), + ("user_led", 2, Pins("A5"), IOStandard("LVCMOS33")), + ("user_led", 3, Pins("B5"), IOStandard("LVCMOS33")), + + ("cpu_reset", 0, Pins("M11"), IOStandard("LVCMOS33")), + + ("user_btn", 0, Pins("B4"), IOStandard("LVCMOS33")), + ("user_btn", 1, Pins("C4"), IOStandard("LVCMOS33")), + ("user_btn", 2, Pins("B3"), IOStandard("LVCMOS33")), + ("user_btn", 3, Pins("C3"), IOStandard("LVCMOS33")), + + ("user_dip", 0, Pins("E4"), IOStandard("LVCMOS33")), + ("user_dip", 1, Pins("D4"), IOStandard("LVCMOS33")), + ("user_dip", 2, Pins("F5"), IOStandard("LVCMOS33")), + ("user_dip", 3, Pins("F4"), IOStandard("LVCMOS33")), + + ("serial", 0, + Subsignal("cts", Pins("A19")), + Subsignal("rts", Pins("C18")), + Subsignal("tx", Pins("C19")), + Subsignal("rx", Pins("A20")), + IOStandard("LVCMOS18") + ), + + ("ddram", 0, + Subsignal("a", Pins( + "AH8 AG8 AF8 AG10 AG11 AH9 AG9 AH13", + "AK10 AJ10 AL8 AK8 AL12 AK12"), + IOStandard("SSTL12_DCI")), + Subsignal("ba", Pins("AL10 AL11"), IOStandard("SSTL12_DCI")), + Subsignal("bg", Pins("AE14 AE13"), IOStandard("SSTL12_DCI")), + Subsignal("ras_n", Pins("AF11"), IOStandard("SSTL12_DCI")), # A16 + Subsignal("cas_n", Pins("AE12"), IOStandard("SSTL12_DCI")), # A15 + Subsignal("we_n", Pins("AC12"), IOStandard("SSTL12_DCI")), # A14 + Subsignal("cs_n", Pins("AD12"), IOStandard("SSTL12_DCI")), + Subsignal("act_n", Pins("AD14"), IOStandard("SSTL12_DCI")), + Subsignal("alert_n", Pins("AF13"), IOStandard("SSTL12_DCI")), + Subsignal("par", Pins("AC13"), IOStandard("SSTL12_DCI")), + Subsignal("dm", Pins("AH18 AD15 AM16 AP18 AE18 AH22 AL20 AP19"), + IOStandard("POD12_DCI")), + Subsignal("dq", Pins( + "AG14 AG15 AF15 AF16 AF17 AE17 AG18 AF18", + "AD16 AD17 AB14 AA14 AB15 AB16 AC16 AC17", + + "AJ15 AJ16 AK17 AJ17 AL18 AK18 AL15 AL16", + "AN16 AN17 AP15 AP16 AN18 AM18 AP13 AN13", + + "AA20 AA19 AD19 AC18 AE20 AD20 AC19 AB19", + "AE24 AE23 AF22 AF21 AG20 AG19 AH21 AG21", + + "AJ22 AJ21 AK20 AJ20 AK19 AJ19 AL23 AL22", + "AN23 AM23 AP23 AN22 AP22 AP21 AN19 AM19", + ), + IOStandard("POD12_DCI")), + Subsignal("dqs_p", Pins("AH14 AA16 AK15 AM14 AA18 AF23 AK22 AM21"), + IOStandard("DIFF_POD12_DCI")), + Subsignal("dqs_n", Pins("AJ14 AA15 AK14 AN14 AB18 AG23 AK23 AN21"), + IOStandard("DIFF_POD12_DCI")), + Subsignal("clk_p", Pins("AH11"), IOStandard("DIFF_SSTL12_DCI")), + Subsignal("clk_n", Pins("AJ11"), IOStandard("DIFF_SSTL12_DCI")), + Subsignal("cke", Pins("AB13"), IOStandard("SSTL12_DCI")), + Subsignal("odt", Pins("AF10"), IOStandard("SSTL12_DCI")), + Subsignal("reset_n", Pins("AF12"), IOStandard("LVCMOS12")), + Misc("SLEW=FAST"), + ), +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(XilinxPlatform): + default_clk_name = "clk125" + default_clk_period = 1e9/125e6 + + def __init__(self): + XilinxPlatform.__init__(self, "xczu7ev-ffvc1156-2-i", _io, toolchain="vivado") + + def create_programmer(self): + return VivadoProgrammer() + + def do_finalize(self, fragment): + XilinxPlatform.do_finalize(self, fragment) + self.add_platform_command("set_property INTERNAL_VREF {{0.84}} [get_iobanks 65]") + self.add_platform_command("set_property INTERNAL_VREF {{0.84}} [get_iobanks 66]") diff --git a/litex_boards/targets/zcu104.py b/litex_boards/targets/zcu104.py new file mode 100755 index 0000000000..00fa88b026 --- /dev/null +++ b/litex_boards/targets/zcu104.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +import argparse + +from migen import * +from migen.genlib.io import CRG + +from litex_boards.platforms import zcu104 + +from litex.soc.cores.clock import * +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * + +from litedram.modules import EDY4016A +from litedram.phy import usddrphy + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) + self.clock_domains.cd_pll4x = ClockDomain(reset_less=True) + self.clock_domains.cd_clk500 = ClockDomain() + self.clock_domains.cd_ic = ClockDomain() + + self.submodules.pll = pll = USMMCM(speedgrade=-2) + pll.register_clkin(platform.request("clk125"), 125e6) + + pll.create_clkout(self.cd_pll4x, sys_clk_freq*4, buf=None, with_reset=False) + pll.create_clkout(self.cd_clk500, 500e6, with_reset=False) + + self.specials += [ + Instance("BUFGCE_DIV", name="main_bufgce_div", + p_BUFGCE_DIVIDE=4, + i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys.clk), + Instance("BUFGCE", name="main_bufgce", + i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys4x.clk), + AsyncResetSynchronizer(self.cd_clk500, ~pll.locked), + ] + + ic_reset_counter = Signal(max=64, reset=63) + ic_reset = Signal(reset=1) + self.sync.clk500 += \ + If(ic_reset_counter != 0, + ic_reset_counter.eq(ic_reset_counter - 1) + ).Else( + ic_reset.eq(0) + ) + ic_rdy = Signal() + ic_rdy_counter = Signal(max=64, reset=63) + self.cd_sys.rst.reset = 1 + self.comb += self.cd_ic.clk.eq(self.cd_sys.clk) + self.sync.ic += [ + If(ic_rdy, + If(ic_rdy_counter != 0, + ic_rdy_counter.eq(ic_rdy_counter - 1) + ).Else( + self.cd_sys.rst.eq(0) + ) + ) + ] + self.specials += [ + Instance("IDELAYCTRL", p_SIM_DEVICE="ULTRASCALE", + i_REFCLK=ClockSignal("clk500"), i_RST=ic_reset, + o_RDY=ic_rdy), + AsyncResetSynchronizer(self.cd_ic, ic_reset) + ] + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCSDRAM): + def __init__(self, sys_clk_freq=int(125e6), **kwargs): + platform = zcu104.Platform() + + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # DDR4 SDRAM ------------------------------------------------------------------------------- + if not self.integrated_main_ram_size: + self.submodules.ddrphy = usddrphy.USDDRPHY(platform.request("ddram"), + memtype = "DDR4", + sim_device = "ULTRASCALE_PLUS", + iodelay_clk_freq = 500e6, + sys_clk_freq = sys_clk_freq) + self.add_csr("ddrphy") + self.add_constant("USDDRPHY", None) + # FIXME: Use correct DDR4 module + sdram_module = EDY4016A(sys_clk_freq, "1:4") + self.register_sdram(self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on ZCU104") + 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()