diff --git a/litex_boards/platforms/decklink_quad_hdmi_recorder.py b/litex_boards/platforms/decklink_quad_hdmi_recorder.py index f319ace..0453d60 100644 --- a/litex_boards/platforms/decklink_quad_hdmi_recorder.py +++ b/litex_boards/platforms/decklink_quad_hdmi_recorder.py @@ -4,6 +4,8 @@ # Copyright (c) 2021 Florent Kermarrec # SPDX-License-Identifier: BSD-2-Clause +# Work-In-Progress... + from litex.build.generic_platform import * from litex.build.xilinx import XilinxPlatform, VivadoProgrammer @@ -14,6 +16,12 @@ _io = [ # TODO (We'll use the 100MHz PCIe Clock for now). + # Debug. + ("debug", 0, Pins("AL34"), IOStandard("LVCMOS25")), + ("debug", 1, Pins("AM34"), IOStandard("LVCMOS25")), + ("debug", 2, Pins("AN34"), IOStandard("LVCMOS25")), + ("debug", 3, Pins("AP34"), IOStandard("LVCMOS25")), + # SPIFlash (MX25L25645GSXDI). # TODO (Probably similar to KCU105). @@ -56,9 +64,42 @@ _io = [ Subsignal("tx_n", Pins("AC3 AE3 AG3 AH5 AK5 AL3 AM5 AN3")) ), - # DRAM (H5TQ4G63CFR). - - # TODO. + # DDR3 SDRAM (H5TQ4G63CFR). + ("ddram", 0, + Subsignal("a", Pins( + "AP16 AM19 AL17 AM14 AL19 AL14 AJ18 AK16", + "AJ19 AK17 AP18 AM17 AL18 AH17 AH14"), + IOStandard("SSTL15_DCI")), + Subsignal("ba", Pins("AN14 AN19 AP14"), IOStandard("SSTL15_DCI")), + Subsignal("ras_n", Pins("AN16"), IOStandard("SSTL15_DCI")), + Subsignal("cas_n", Pins("AM16"), IOStandard("SSTL15_DCI")), + Subsignal("we_n", Pins("AP15"), IOStandard("SSTL15_DCI")), + Subsignal("cs_n", Pins("AM15"), IOStandard("SSTL15_DCI")), + Subsignal("dm", Pins("AH26 AN26"), + IOStandard("SSTL15_DCI"), + Misc("DATA_RATE=DDR")), + Subsignal("dq", Pins( + "AM27 AK28 AH27 AJ28 AK26 AH28 AM26 AK27", + "AP29 AP28 AM30 AN27 AM29 AN28 AL30 AL29"), + IOStandard("SSTL15_DCI"), + Misc("ODT=RTT_40"), + Misc("DATA_RATE=DDR")), + Subsignal("dqs_p", Pins("AL27 AN29"), + IOStandard("DIFF_SSTL15_DCI"), + Misc("ODT=RTT_40"), + Misc("DATA_RATE=DDR")), + Subsignal("dqs_n", Pins("AL28 AP30"), + IOStandard("DIFF_SSTL15_DCI"), + Misc("ODT=RTT_40"), + Misc("DATA_RATE=DDR")), + Subsignal("clk_p", Pins("AN18"), IOStandard("DIFF_SSTL15_DCI"), Misc("DATA_RATE=DDR")), + Subsignal("clk_n", Pins("AN17"), IOStandard("DIFF_SSTL15_DCI"), Misc("DATA_RATE=DDR")), + Subsignal("cke", Pins("AK18"), IOStandard("SSTL15_DCI")), + Subsignal("odt", Pins("AL15"), IOStandard("SSTL15_DCI")), + Subsignal("reset_n", Pins("AK15"), IOStandard("SSTL15")), + Misc("SLEW=FAST"), + Misc("OUTPUT_IMPEDANCE=RDRV_40_40") + ), # HDMI (through PI3HDX1204) ("hdmi_in", 0, # PCIe Edge Side. diff --git a/litex_boards/targets/decklink_quad_hdmi_recorder.py b/litex_boards/targets/decklink_quad_hdmi_recorder.py index d9f5b47..e4451fc 100755 --- a/litex_boards/targets/decklink_quad_hdmi_recorder.py +++ b/litex_boards/targets/decklink_quad_hdmi_recorder.py @@ -6,6 +6,8 @@ # Copyright (c) 2021 Florent Kermarrec # SPDX-License-Identifier: BSD-2-Clause +# Work-In-Progress... + import os import argparse @@ -17,6 +19,9 @@ from litex.soc.cores.clock import * from litex.soc.integration.soc_core import * from litex.soc.integration.builder import * +from litedram.modules import MT41J256M16 +from litedram.phy import usddrphy + from litepcie.phy.uspciephy import USPCIEPHY from litepcie.software import generate_litepcie_software @@ -24,15 +29,27 @@ from litepcie.software import generate_litepcie_software class _CRG(Module): def __init__(self, platform, sys_clk_freq): - self.clock_domains.cd_sys = ClockDomain() + 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_idelay = ClockDomain() # # # self.submodules.pll = pll = USMMCM(speedgrade=-2) self.comb += pll.reset.eq(ResetSignal("pcie")) pll.register_clkin(ClockSignal("pcie"), 250e6) - pll.create_clkout(self.cd_sys, sys_clk_freq) + pll.create_clkout(self.cd_pll4x, sys_clk_freq*4, buf=None, with_reset=False) + pll.create_clkout(self.cd_idelay, 200e6) platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst. + 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), + ] + self.submodules.idelayctrl = USIDELAYCTRL(cd_ref=self.cd_idelay, cd_sys=self.cd_sys) # BaseSoC ------------------------------------------------------------------------------------------ @@ -50,6 +67,19 @@ class BaseSoC(SoCCore): # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) + # DDR3 SDRAM ------------------------------------------------------------------------------- + if not self.integrated_main_ram_size: + self.submodules.ddrphy = usddrphy.USDDRPHY(platform.request("ddram"), + memtype = "DDR3", + sys_clk_freq = sys_clk_freq, + iodelay_clk_freq = 200e6) + self.add_sdram("sdram", + phy = self.ddrphy, + module = MT41J256M16(sys_clk_freq, "1:4"), + size = 0x40000000, + l2_cache_size = kwargs.get("l2_size", 8192) + ) + # PCIe ------------------------------------------------------------------------------------- if with_pcie: self.submodules.pcie_phy = USPCIEPHY(platform, platform.request("pcie_x4"), @@ -58,8 +88,8 @@ class BaseSoC(SoCCore): bar0_size = 0x20000) self.add_pcie(phy=self.pcie_phy, ndmas=1) # False Paths (FIXME: Improve integration). - platform.toolchain.pre_placement_commands.append("set_false_path -from [get_clocks main_clkout_1] -to [get_clocks pcie_clk_1]") - platform.toolchain.pre_placement_commands.append("set_false_path -from [get_clocks pcie_clk_1] -to [get_clocks main_clkout_1]") + platform.toolchain.pre_placement_commands.append("set_false_path -from [get_clocks sys_clk_1] -to [get_clocks pcie_clk_1]") + platform.toolchain.pre_placement_commands.append("set_false_path -from [get_clocks pcie_clk_1] -to [get_clocks sys_clk_1]") # Build --------------------------------------------------------------------------------------------