From 608541d5b83b986a9d0c4da5a6f8b6404f0d3ec8 Mon Sep 17 00:00:00 2001 From: Piotr Binkowski Date: Tue, 25 Feb 2020 12:21:26 +0100 Subject: [PATCH] add ZCU104 board --- litex_boards/platforms/zcu104.py | 106 +++++++++++++++++++++++++++++ litex_boards/targets/zcu104.py | 110 +++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 litex_boards/platforms/zcu104.py create mode 100755 litex_boards/targets/zcu104.py diff --git a/litex_boards/platforms/zcu104.py b/litex_boards/platforms/zcu104.py new file mode 100644 index 0000000..67e82e6 --- /dev/null +++ b/litex_boards/platforms/zcu104.py @@ -0,0 +1,106 @@ +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( + "AH16 AG14 AG15 AF15 AF16 AJ14 AH14 AF17", + "AK17 AJ17 AK14 AK15 AL18 AK18"), + IOStandard("SSTL12_DCI")), + Subsignal("ba", Pins("AL15 AL16"), IOStandard("SSTL12_DCI")), + Subsignal("bg", Pins("AC16 AB16"), IOStandard("SSTL12_DCI")), + Subsignal("ras_n", Pins("AD15"), IOStandard("SSTL12_DCI")), # A16 + Subsignal("cas_n", Pins("AA14"), IOStandard("SSTL12_DCI")), # A15 + Subsignal("we_n", Pins("AA16"), IOStandard("SSTL12_DCI")), # A14 + Subsignal("cs_n", Pins("AA15"), IOStandard("SSTL12_DCI")), # also AL17 AN17 AN16 for larger SODIMMs + Subsignal("act_n", Pins("AC17"), IOStandard("SSTL12_DCI")), + #Subsignal("alert_n", Pins("AB15"), IOStandard("SSTL12_DCI")), + #Subsignal("par", Pins("AD16"), IOStandard("SSTL12_DCI")), + #FIXME: Use full bus width + #Subsignal("dm", Pins("AH22 AE18 AL20 AP19 AF11 AH12 AK13 AN12"), + Subsignal("dm", Pins("AF11 AH12 AK13 AN12"), + IOStandard("POD12_DCI")), + Subsignal("dq", Pins( +# "AE24 AE23 AF22 AF21 AG20 AG19 AH21 AG21", +# "AA20 AA19 AD19 AC18 AE20 AD20 AC19 AB19", + +# "AJ22 AJ21 AK20 AJ20 AK19 AJ19 AL23 AL22", +# "AN23 AM23 AP23 AN22 AP22 AP21 AN19 AM19", + + "AC13 AB13 AF12 AE12 AF13 AE13 AE14 AD14", + "AG8 AF8 AG10 AG11 AH13 AG13 AJ11 AH11", + + "AK9 AJ9 AK10 AJ10 AL12 AK12 AL10 AL11", + "AM8 AM9 AM10 AM11 AP11 AN11 AP9 AP10" + ), + IOStandard("POD12_DCI")), + #Subsignal("dqs_p", Pins("AF23 AA18 AK22 AM21 AC12 AG9 AK8 AN9"), + # IOStandard("DIFF_POD12_DCI")), + Subsignal("dqs_p", Pins("AC12 AG9 AK8 AN9"), + IOStandard("DIFF_POD12_DCI")), + #Subsignal("dqs_n", Pins("AG23 AB18 AK23 AN21 AD12 AH9 AL8 AN8"), + # IOStandard("DIFF_POD12_DCI")), + Subsignal("dqs_n", Pins("AD12 AH9 AL8 AN8"), + IOStandard("DIFF_POD12_DCI")), + Subsignal("clk_p", Pins("AF18"), IOStandard("DIFF_SSTL12_DCI")), # also AJ16 for larger SODIMMs + Subsignal("clk_n", Pins("AG18"), IOStandard("DIFF_SSTL12_DCI")), # also AJ15 for larger SODIMMs + Subsignal("cke", Pins("AD17"), IOStandard("SSTL12_DCI")), # also AM15 for larger SODIMMs + Subsignal("odt", Pins("AE15"), IOStandard("SSTL12_DCI")), # also AM16 for larger SODIMMs + Subsignal("reset_n", Pins("AB14"), 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 0000000..6a998c3 --- /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 KVR21SE15S84 +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, + cmd_latency = 1, + sys_clk_freq = sys_clk_freq) + self.add_csr("ddrphy") + self.add_constant("USDDRPHY", None) + sdram_module = KVR21SE15S84(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()