Skip to content

Instantly share code, notes, and snippets.

@suarezvictor
Created June 13, 2024 23:14
Show Gist options
  • Save suarezvictor/d87b7a4c59a3a4e536d20f8e06b5c13b to your computer and use it in GitHub Desktop.
Save suarezvictor/d87b7a4c59a3a4e536d20f8e06b5c13b to your computer and use it in GitHub Desktop.
FullHD on Arty board using Litex
# Copyright (c) 2024 Victor Suarez Rovere <[email protected]>
# SPDX-License-Identifier: AGPL-3.0-only
# code portions from LiteX framework (C) Enjoy-Digital https://github.com/enjoy-digital/litex
import sys
import argparse
from migen import *
from litex.soc.cores.clock import *
from litex.soc.integration.builder import *
from litex.soc.integration.soc_core import *
from litex.build.generic_platform import *
from litex_boards.platforms import digilent_arty
from litex.soc.cores.video import VideoS7HDMIPHY as DVIPHY
class _CRG(Module):
def __init__(self, platform, sys_clk_freq, video_clock):
self.rst = Signal()
self.clock_domains.cd_sys = ClockDomain()
self.submodules.pll = pll = S7PLL(speedgrade=-1)
rst = ~platform.request("cpu_reset")
self.comb += pll.reset.eq(rst | self.rst)
pll.register_clkin(platform.request("clk100"), 100e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
self.clock_domains.cd_dvi = ClockDomain()
self.clock_domains.cd_dvi5x = ClockDomain()
pll.create_clkout(self.cd_dvi, video_clock)
pll.create_clkout(self.cd_dvi5x, 5*video_clock)
# Ignore sys_clk to pll.clkin path created by SoC's rst.
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin)
def build_arty(args):
platform = digilent_arty.Platform(variant="a7-35")
sys_clk_freq = int(100e6)
video_timings = "1920x1080@60Hz"; video_clock = 150e6
soc = SoCCore(platform, sys_clk_freq, **soc_core_argdict(args))
soc.submodules.crg = _CRG(platform, sys_clk_freq, video_clock)
# Video -------------------------------------------------------------------------------------
dvi_pins = "45230167"
pmod_dvi = "pmodc"
dvi_iostd = "TMDS_33"
platform.add_extension([("dvi_out", 0,
Subsignal("data0_p", Pins(f"{pmod_dvi}:{dvi_pins[0]}"), IOStandard(dvi_iostd)), #B0+
Subsignal("data0_n", Pins(f"{pmod_dvi}:{dvi_pins[1]}"), IOStandard(dvi_iostd)), #B0-
Subsignal("data1_p", Pins(f"{pmod_dvi}:{dvi_pins[2]}"), IOStandard(dvi_iostd)), #G1+
Subsignal("data1_n", Pins(f"{pmod_dvi}:{dvi_pins[3]}"), IOStandard(dvi_iostd)), #G1-
Subsignal("data2_p", Pins(f"{pmod_dvi}:{dvi_pins[4]}"), IOStandard(dvi_iostd)), #R2+
Subsignal("data2_n", Pins(f"{pmod_dvi}:{dvi_pins[5]}"), IOStandard(dvi_iostd)), #R2-
Subsignal("clk_p", Pins(f"{pmod_dvi}:{dvi_pins[6]}"), IOStandard(dvi_iostd)),
Subsignal("clk_n", Pins(f"{pmod_dvi}:{dvi_pins[7]}"), IOStandard(dvi_iostd)))
])
video_clock_domain = "dvi"
soc.submodules.videophy = DVIPHY(platform.request("dvi_out"), clock_domain=video_clock_domain)
soc.add_video_terminal(phy=soc.videophy, timings=video_timings, clock_domain=video_clock_domain)
return soc
def main():
from litex.build.parser import LiteXArgumentParser
parser = LiteXArgumentParser(platform=digilent_arty.Platform, description="LiteX SoC on Arty A7")
args = parser.parse_args()
soc = build_arty(args)
builder = Builder(soc)
builder.build()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment