From 77cb866233f68e5a5374a895a4800a9b50320e8c Mon Sep 17 00:00:00 2001 From: Alessandro Comodi Date: Mon, 7 Mar 2022 17:16:49 +0100 Subject: [PATCH] antmicro_datacenter: add HDMI output Signed-off-by: Alessandro Comodi --- .../antmicro_datacenter_ddr4_test_board.py | 25 ++++-- .../antmicro_datacenter_ddr4_test_board.py | 89 ++++++++++++------- 2 files changed, 76 insertions(+), 38 deletions(-) diff --git a/litex_boards/platforms/antmicro_datacenter_ddr4_test_board.py b/litex_boards/platforms/antmicro_datacenter_ddr4_test_board.py index 8372a70..ae9e569 100644 --- a/litex_boards/platforms/antmicro_datacenter_ddr4_test_board.py +++ b/litex_boards/platforms/antmicro_datacenter_ddr4_test_board.py @@ -98,13 +98,12 @@ _io = [ # HyperRAM ("hyperram", 0, - Subsignal("clk_n", Pins("AE26")), - Subsignal("clk_p", Pins("AD26")), - Subsignal("rst_n", Pins("AC24")), - Subsignal("cs_n", Pins("AC26")), - Subsignal("dq", Pins("AE23 AD25 AF24 AE22 AF23 AF25 AE25 AD24")), - Subsignal("rwds", Pins("AD23")), - IOStandard("LVCMOS33") + Subsignal("clk_n", Pins("AE26"), IOStandard("TMDS_33")), + Subsignal("clk_p", Pins("AD26"), IOStandard("TMDS_33")), + Subsignal("rst_n", Pins("AC24"), IOStandard("LVCMOS33")), + Subsignal("cs_n", Pins("AC26"), IOStandard("LVCMOS33")), + Subsignal("dq", Pins("AE23 AD25 AF24 AE22 AF23 AF25 AE25 AD24"), IOStandard("LVCMOS33")), + Subsignal("rwds", Pins("AD23"), IOStandard("LVCMOS33")), ), # SD Card @@ -123,6 +122,18 @@ _io = [ Subsignal("sda", Pins("Y6")), IOStandard("SSTL12_T_DCI"), ), + + # HDMI Out + ("hdmi_out", 0, + Subsignal("clk_p", Pins("B15"), IOStandard("TMDS_33")), + Subsignal("clk_n", Pins("A15"), IOStandard("TMDS_33")), + Subsignal("data0_p", Pins("B14"), IOStandard("TMDS_33")), + Subsignal("data0_n", Pins("A14"), IOStandard("TMDS_33")), + Subsignal("data1_p", Pins("A13"), IOStandard("TMDS_33")), + Subsignal("data1_n", Pins("A12"), IOStandard("TMDS_33")), + Subsignal("data2_p", Pins("B10"), IOStandard("TMDS_33")), + Subsignal("data2_n", Pins("A10"), IOStandard("TMDS_33")), + ), ] # Platform ----------------------------------------------------------------------------------------- diff --git a/litex_boards/targets/antmicro_datacenter_ddr4_test_board.py b/litex_boards/targets/antmicro_datacenter_ddr4_test_board.py index c4cbdf2..df80f51 100755 --- a/litex_boards/targets/antmicro_datacenter_ddr4_test_board.py +++ b/litex_boards/targets/antmicro_datacenter_ddr4_test_board.py @@ -20,6 +20,7 @@ from litex.soc.integration.soc import SoCRegion from litex.soc.integration.builder import * from litex.soc.cores.led import LedChaser from litex.soc.cores.bitbang import I2CMaster +from litex.soc.cores.video import VideoS7HDMIPHY from litedram.modules import MTA18ASF2G72PZ from litedram.phy.s7ddrphy import A7DDRPHY @@ -33,17 +34,23 @@ from litex.soc.cores.hyperbus import HyperRAM # CRG ---------------------------------------------------------------------------------------------- class _CRG(Module): - def __init__(self, platform, sys_clk_freq, iodelay_clk_freq): + def __init__(self, platform, sys_clk_freq, iodelay_clk_freq, with_video_pll=False): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys2x = ClockDomain(reset_less=True) self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) self.clock_domains.cd_idelay = ClockDomain() + self.clock_domains.cd_hdmi = ClockDomain() + self.clock_domains.cd_hdmi5x = ClockDomain() + # # # + # Clk. + clk100 = platform.request("clk100") + self.submodules.pll = pll = S7PLL(speedgrade=-1) - pll.register_clkin(platform.request("clk100"), 100e6) + pll.register_clkin(clk100, 100e6) pll.create_clkout(self.cd_sys, sys_clk_freq) pll.create_clkout(self.cd_sys2x, 2 * sys_clk_freq) pll.create_clkout(self.cd_sys4x, 4 * sys_clk_freq) @@ -52,13 +59,21 @@ class _CRG(Module): self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay) + # Video PLL. + if with_video_pll: + self.submodules.video_pll = video_pll = S7MMCM(speedgrade=-1) + video_pll.register_clkin(clk100, 100e6) + video_pll.create_clkout(self.cd_hdmi, 40e6) + video_pll.create_clkout(self.cd_hdmi5x, 5*40e6) + + # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): def __init__(self, *, sys_clk_freq=int(100e6), iodelay_clk_freq=200e6, with_ethernet=False, with_etherbone=False, eth_ip="192.168.1.50", eth_dynamic_ip=False, with_hyperram=False, with_sdcard=False, with_jtagbone=True, with_uartbone=False, - with_led_chaser=True, eth_reset_time, **kwargs): + with_led_chaser=True, with_video_terminal=False, with_video_framebuffer=False, **kwargs): platform = datacenter_ddr4_test_board.Platform() # SoCCore ---------------------------------------------------------------------------------- @@ -67,7 +82,8 @@ class BaseSoC(SoCCore): **kwargs) # CRG -------------------------------------------------------------------------------------- - self.submodules.crg = _CRG(platform, sys_clk_freq, iodelay_clk_freq=iodelay_clk_freq) + with_video_pll = (with_video_terminal or with_video_framebuffer) + self.submodules.crg = _CRG(platform, sys_clk_freq, iodelay_clk_freq=iodelay_clk_freq, with_video_pll=with_video_pll) # DDR4 SDRAM RDIMM ------------------------------------------------------------------------- if not self.integrated_main_ram_size: @@ -120,6 +136,14 @@ class BaseSoC(SoCCore): pads = platform.request_all("user_led"), sys_clk_freq = sys_clk_freq) + # Video ------------------------------------------------------------------------------------ + if with_video_terminal or with_video_framebuffer: + self.submodules.videophy = VideoS7HDMIPHY(platform.request("hdmi_out"), clock_domain="hdmi") + if with_video_terminal: + self.add_video_terminal(phy=self.videophy, timings="800x600@60Hz", clock_domain="hdmi") + if with_video_framebuffer: + self.add_video_framebuffer(phy=self.videophy, timings="800x600@60Hz", clock_domain="hdmi") + # System I2C (behing multiplexer) ---------------------------------------------------------- i2c_pads = platform.request('i2c') self.submodules.i2c = I2CMaster(i2c_pads) @@ -149,23 +173,25 @@ class LiteDRAMSettingsEncoder(json.JSONEncoder): def main(): from litex.soc.integration.soc import LiteXSoCArgumentParser - parser = LiteXSoCArgumentParser(description="LiteX SoC on LPDDR4 Test Board") + parser = LiteXSoCArgumentParser(description="LiteX SoC on DDR4 Datacenter Test Board") target_group = parser.add_argument_group(title="Target options") - target_group.add_argument("--build", action="store_true", help="Build bitstream.") - target_group.add_argument("--load", action="store_true", help="Load bitstream.") - target_group.add_argument("--flash", action="store_true", help="Flash bitstream.") - target_group.add_argument("--sys-clk-freq", default=100e6, help="System clock frequency.") - target_group.add_argument("--iodelay-clk-freq", default=200e6, help="IODELAYCTRL frequency.") - ethopts = target_group.add_mutually_exclusive_group() - ethopts.add_argument("--with-ethernet", action="store_true", help="Add Ethernet.") - ethopts.add_argument("--with-etherbone", action="store_true", help="Add EtherBone.") - target_group.add_argument("--eth-ip", default="192.168.1.50", help="Ethernet/Etherbone IP address.") - target_group.add_argument("--eth-dynamic-ip", action="store_true", help="Enable dynamic Ethernet IP addresses setting.") - target_group.add_argument("--eth-reset-time", default="10e-3", help="Duration of Ethernet PHY reset") - target_group.add_argument("--with-hyperram", action="store_true", help="Add HyperRAM.") - target_group.add_argument("--with-sdcard", action="store_true", help="Add SDCard.") - target_group.add_argument("--with-jtagbone", action="store_true", help="Add JTAGBone.") - target_group.add_argument("--with-uartbone", action="store_true", help="Add UartBone on 2nd serial.") + target_group.add_argument("--build", action="store_true", help="Build bitstream") + target_group.add_argument("--load", action="store_true", help="Load bitstream") + target_group.add_argument("--flash", action="store_true", help="Flash bitstream") + target_group.add_argument("--sys-clk-freq", default=100e6, help="System clock frequency") + target_group.add_argument("--iodelay-clk-freq", default=200e6, help="IODELAYCTRL frequency") + ethopts = target.add_mutually_exclusive_group() + ethopts.add_argument("--with-ethernet", action="store_true", help="Add Ethernet") + ethopts.add_argument("--with-etherbone", action="store_true", help="Add EtherBone") + target_group.add_argument("--eth-ip", default="192.168.1.50", help="Ethernet/Etherbone IP address") + target_group.add_argument("--eth-dynamic-ip", action="store_true", help="Enable dynamic Ethernet IP addresses setting") + target_group.add_argument("--eth-reset-time", default="10e-3", help="Duration of Ethernet PHY reset") + target_group.add_argument("--with-hyperram", action="store_true", help="Add HyperRAM") + target_group.add_argument("--with-sdcard", action="store_true", help="Add SDCard") + target_group.add_argument("--with-jtagbone", action="store_true", help="Add JTAGBone") + target_group.add_argument("--with-uartbone", action="store_true", help="Add UartBone on 2nd serial") + target_group.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal (HDMI)") + target_group.add_argument("--with-video-framebuffer", action="store_true", help="Enable Video Framebuffer (HDMI)") builder_args(parser) soc_core_args(parser) vivado_build_args(parser) @@ -174,17 +200,18 @@ def main(): assert not (args.with_etherbone and args.eth_dynamic_ip) soc = BaseSoC( - sys_clk_freq = int(float(args.sys_clk_freq)), - iodelay_clk_freq = int(float(args.iodelay_clk_freq)), - with_ethernet = args.with_ethernet, - with_etherbone = args.with_etherbone, - eth_ip = args.eth_ip, - eth_dynamic_ip = args.eth_dynamic_ip, - eth_reset_time = args.eth_reset_time, - with_hyperram = args.with_hyperram, - with_sdcard = args.with_sdcard, - with_jtagbone = args.with_jtagbone, - with_uartbone = args.with_uartbone, + sys_clk_freq = int(float(args.sys_clk_freq)), + iodelay_clk_freq = int(float(args.iodelay_clk_freq)), + with_ethernet = args.with_ethernet, + with_etherbone = args.with_etherbone, + eth_ip = args.eth_ip, + eth_dynamic_ip = args.eth_dynamic_ip, + with_hyperram = args.with_hyperram, + with_sdcard = args.with_sdcard, + with_jtagbone = args.with_jtagbone, + with_uartbone = args.with_uartbone, + with_video_terminal = args.with_video_terminal, + with_video_framebuffer = args.with_video_framebuffer, **soc_core_argdict(args)) builder = Builder(soc, **builder_argdict(args)) vns = builder.build(**vivado_build_argdict(args), run=args.build)