Skip to content

Commit 27032c7

Browse files
committed
targets/decklink_mini_4k: Generate exact video clocks
The 100MHz input cannot generate the requested 148.5MHz, 594MHz and 200MHz clocks simultaneously with the 7-series PLL. Vivado consequently selected 147.5MHz, 590MHz and 196.667MHz, leaving HDMI outside its nominal timing and the IDELAY reference inconsistent with its 200MHz setting. Use the clock-capable 24MHz input and an MMCM for the system, DDR3 and optional HDMI domains. Use the 100MHz input with one auxiliary PLL for exact 200MHz IDELAY and 150MHz SATA reference clocks. Resolve the non-dedicated clock route override from the generated auxiliary PLL input signal instead of hard-coded net names, and declare the two independent clock trees asynchronous.
1 parent 4d62211 commit 27032c7

1 file changed

Lines changed: 36 additions & 24 deletions

File tree

litex_boards/targets/decklink_mini_4k.py

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,42 +32,53 @@
3232
# CRG ----------------------------------------------------------------------------------------------
3333

3434
class _CRG(LiteXModule):
35-
def __init__(self, platform, sys_clk_freq):
35+
def __init__(self, platform, sys_clk_freq, with_video=False):
3636
self.rst = Signal()
3737
self.cd_sys = ClockDomain()
3838
self.cd_sys4x = ClockDomain()
3939
self.cd_sys4x_dqs = ClockDomain()
4040
self.cd_idelay = ClockDomain()
41-
self.cd_hdmi = ClockDomain()
4241

4342
# # #
4443

45-
# Clk.
44+
# Clks.
45+
clk24 = platform.request("clk24")
4646
clk100 = platform.request("clk100")
47-
platform.add_platform_command("set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk100_IBUF]")
48-
platform.add_platform_command("set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets s7pll0_clkin]")
49-
50-
# Main PLL.
51-
self.pll = pll = S7PLL(speedgrade=-1)
52-
self.comb += pll.reset.eq(self.rst)
53-
pll.register_clkin(clk100, 100e6)
54-
pll.create_clkout(self.cd_sys, sys_clk_freq)
55-
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
56-
pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
57-
pll.create_clkout(self.cd_idelay, 200e6, margin=1e-1) # FIXME: Re-arrange clocking.
58-
pll.create_clkout(self.cd_hdmi, 148.5e6, margin=2e-2) # FIXME: Use a second PLL or move to clkout0 that has fractional support.
59-
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst.
47+
48+
# Main MMCM.
49+
# The 24MHz input allows exact 148.5/594MHz video and DDR3 clocks.
50+
self.mmcm = mmcm = S7MMCM(speedgrade=-1)
51+
self.comb += mmcm.reset.eq(self.rst)
52+
mmcm.register_clkin(clk24, 24e6)
53+
mmcm.create_clkout(self.cd_sys, sys_clk_freq)
54+
mmcm.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
55+
mmcm.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
56+
if with_video:
57+
self.cd_hdmi = ClockDomain()
58+
mmcm.create_clkout(self.cd_hdmi, 148.5e6, margin=0)
59+
# Ignore sys_clk to mmcm.clkin path created by SoC's reset.
60+
platform.add_false_path_constraints(self.cd_sys.clk, mmcm.clkin)
61+
62+
# Auxiliary PLL.
63+
# Generate exact IDELAY and SATA reference clocks from the 100MHz input.
64+
self.aux_pll = aux_pll = S7PLL(speedgrade=-1)
65+
self.comb += aux_pll.reset.eq(self.rst)
66+
aux_pll.register_clkin(clk100, 100e6)
67+
aux_pll.create_clkout(self.cd_idelay, 200e6, margin=0)
68+
self.cd_sata_refclk = ClockDomain()
69+
aux_pll.create_clkout(self.cd_sata_refclk, 150e6, margin=0)
70+
platform.add_false_path_constraints(self.cd_sys.clk, aux_pll.clkin)
71+
platform.add_platform_command(
72+
"set aux_pll_clkin [get_nets -quiet {{{clkin}}}]\n"
73+
"if {{[llength $aux_pll_clkin]}} {{\n"
74+
" set_property CLOCK_DEDICATED_ROUTE FALSE $aux_pll_clkin\n"
75+
"}}",
76+
clkin=aux_pll.clkin
77+
)
6078

6179
# IDELAY Ctrl.
6280
self.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
6381

64-
# SATA PLL.
65-
self.cd_sata_refclk = ClockDomain()
66-
self.sata_pll = sata_pll = S7PLL(speedgrade=-1)
67-
self.comb += sata_pll.reset.eq(self.rst)
68-
sata_pll.register_clkin(clk100, 100e6)
69-
sata_pll.create_clkout(self.cd_sata_refclk, 150e6)
70-
7182
# BaseSoC ------------------------------------------------------------------------------------------
7283

7384
class BaseSoC(SoCMini):
@@ -82,7 +93,8 @@ def __init__(self, sys_clk_freq=100e6,
8293
platform = decklink_mini_4k.Platform()
8394

8495
# CRG --------------------------------------------------------------------------------------
85-
self.crg = _CRG(platform, sys_clk_freq)
96+
self.crg = _CRG(platform, sys_clk_freq,
97+
with_video = with_video_terminal or with_video_framebuffer)
8698

8799
# SoCCore ----------------------------------------------------------------------------------
88100
if kwargs.get("uart_name", "serial") == "serial":

0 commit comments

Comments
 (0)