From 8a6f0bd94f6ce3391db6aa185252be6e2767a4e7 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 1 Mar 2023 09:16:51 +0100 Subject: [PATCH] opalkelly_xem8320: Review and update to recent LiteX changes. --- README.md | 1 + litex_boards/platforms/opalkelly_xem8320.py | 22 ++-- litex_boards/targets/opalkelly_xem8320.py | 126 +++++++++++--------- 3 files changed, 80 insertions(+), 69 deletions(-) mode change 100644 => 100755 litex_boards/targets/opalkelly_xem8320.py diff --git a/README.md b/README.md index 7f13c18..ebb9972 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,7 @@ Some of the suported boards, see yours? Give LiteX-Boards a try! ├── numato_nereid ├── numato_tagus ├── ocp_tap_timecard + ├── opalkelly_xem8320 ├── pano_logic_g2 ├── qmtech_10cl006 ├── qmtech_5cefa2 diff --git a/litex_boards/platforms/opalkelly_xem8320.py b/litex_boards/platforms/opalkelly_xem8320.py index f80684e..ca6e158 100644 --- a/litex_boards/platforms/opalkelly_xem8320.py +++ b/litex_boards/platforms/opalkelly_xem8320.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: BSD-2-Clause from litex.build.generic_platform import * -from litex.build.xilinx import XilinxPlatform, VivadoProgrammer +from litex.build.xilinx import Xilinx7SeriesPlatform, VivadoProgrammer # IOs ---------------------------------------------------------------------------------------------- @@ -36,17 +36,17 @@ _io = [ Subsignal("okAA", Pins("T19")), Subsignal("okHU", Pins("U20 U26 T22")), Subsignal("okUH", Pins("V23 T23 U22 U25 U21")), - Subsignal("okUHU", Pins("P26 P25 R26 R25 R23 R22 P21 P20", - "R21 R20 P23 N23 T25 N24 N22 V26", - "N19 V21 N21 W20 W26 W19 Y25 Y26", - "Y22 V22 W21 AA23 Y23 AA24 W25 AA25")), - Misc("SLEW=FAST"), + Subsignal("okUHU", Pins( + "P26 P25 R26 R25 R23 R22 P21 P20", + "R21 R20 P23 N23 T25 N24 N22 V26", + "N19 V21 N21 W20 W26 W19 Y25 Y26", + "Y22 V22 W21 AA23 Y23 AA24 W25 AA25")), IOStandard("LVCMOS18"), + Misc("SLEW=FAST"), ), # TODO: Add SMA & SFP+ - # DDR4 SDRAM ("ddram", 0, Subsignal("a", Pins( @@ -89,7 +89,6 @@ _io = [ # TODO: SYZYGY Connectors & SYZYGY to PMODS! - _connectors = [ ("pmod1", "AC14 AC13 AF15 AF14 AF13 AE13 H13 J13"), ("pmod2", "AB15 AB16 W14 J14 AE15 W15 Y15 J15"), @@ -137,20 +136,21 @@ def sdcard_pmod_io(pmod): ] _sdcard_pmod_io = sdcard_pmod_io("pmod3") # SDCARD PMOD on JD. + # Platform ----------------------------------------------------------------------------------------- -class Platform(XilinxPlatform): +class Platform(Xilinx7SeriesPlatform): default_clk_name = "sys_clk100" default_clk_period = 1e9/100e6 def __init__(self, toolchain="vivado"): - XilinxPlatform.__init__(self, "xcau25p-ffvb676-2-e", _io, _connectors, toolchain=toolchain) + Xilinx7SeriesPlatform.__init__(self, "xcau25p-ffvb676-2-e", _io, _connectors, toolchain=toolchain) def create_programmer(self): return VivadoProgrammer() def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) + Xilinx7SeriesPlatform.do_finalize(self, fragment) self.add_period_constraint(self.lookup_request("sys_clk100", loose=True), 1e9/100e6) self.add_period_constraint(self.lookup_request("ddr_clk100", loose=True), 1e9/100e6) self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 64]") diff --git a/litex_boards/targets/opalkelly_xem8320.py b/litex_boards/targets/opalkelly_xem8320.py old mode 100644 new mode 100755 index 487fc26..3c60dc3 --- a/litex_boards/targets/opalkelly_xem8320.py +++ b/litex_boards/targets/opalkelly_xem8320.py @@ -11,6 +11,8 @@ import os from migen import * from migen.genlib.resetsync import AsyncResetSynchronizer +from litex.gen import * + from litex_boards.platforms import opalkelly_xem8320 from litex.soc.cores.clock import * @@ -18,65 +20,68 @@ from litex.soc.integration.soc_core import * from litex.soc.integration.builder import * from litex.soc.cores.led import LedChaser from litex.soc.cores.video import VideoDVIPHY + from litedram.modules import MT40A512M16 from litedram.phy import usddrphy - - # CRG ---------------------------------------------------------------------------------------------- -class _CRG(Module): - def __init__(self, platform, sys_clk_freq): +class _CRG(LiteXModule): + def __init__(self, platform, sys_clk_freq, with_video_pll=False): self.rst = Signal() - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sys4x = ClockDomain() - self.clock_domains.cd_idelay = ClockDomain() - self.clock_domains.cd_hdmi = ClockDomain() - self.clock_domains.cd_hdmi5x = ClockDomain() + self.cd_sys = ClockDomain() + self.cd_sys4x = ClockDomain() + self.cd_idelay = ClockDomain() + if with_video_pll: + self.cd_hdmi = ClockDomain() + self.cd_hdmi5x = ClockDomain() # # # + + # Clk. clk100 = platform.request("ddr_clk100") - self.submodules.pll = pll = USMMCM(speedgrade=-2) + # PLL. + self.pll = pll = USMMCM(speedgrade=-2) self.comb += pll.reset.eq(self.rst) pll.register_clkin(clk100, 100e6) - pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=False) - pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq) #500 - pll.create_clkout(self.cd_hdmi, 25e6) - pll.create_clkout(self.cd_hdmi5x, 5*25e6) - + pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=False) + pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq) platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst. + self.idelayctrl = USIDELAYCTRL(cd_ref=self.cd_sys4x, cd_sys=self.cd_sys) - # #option for second MMCM for video clocks - # self.submodules.video_pll = video_pll = USMMCM(speedgrade=-2) - # video_pll.reset.eq(self.rst) - # video_pll.register_clkin(self.cd_sys.clk, sys_clk_freq) - # video_pll.create_clkout(self.cd_hdmi, 25e6) - # video_pll.create_clkout(self.cd_hdmi5x, 5*25e6) - - self.submodules.idelayctrl = USIDELAYCTRL(cd_ref=self.cd_sys4x, cd_sys=self.cd_sys) + # Video PLL. + if with_video_pll: + self.video_pll = video_pll = USMMCM(speedgrade=-2) + video_pll.reset.eq(self.rst) + video_pll.register_clkin(self.cd_sys.clk, sys_clk_freq) + video_pll.create_clkout(self.cd_hdmi, 25e6) + video_pll.create_clkout(self.cd_hdmi5x, 5*25e6) # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): - def __init__(self, sys_clk_freq=int(125e6), with_ethernet=False, with_etherbone=False, - eth_ip="192.168.1.50", with_led_chaser=True, - **kwargs): + def __init__(self, sys_clk_freq=int(125e6), + with_ethernet = False, + with_etherbone = False, + eth_ip = "192.168.1.50", + with_led_chaser = True, + with_video_framebuffer = False, + **kwargs): platform = opalkelly_xem8320.Platform() - # CRG -------------------------------------------------------------------------------------- - self.submodules.crg = _CRG(platform, sys_clk_freq) - - kwargs["uart_name"] = "jtag_uart" - # TODO: add okHost FrontPanel API for UART, Data streaing, and Debug + # CRG -------------------------------------------------------------------------------------- + self.crg = _CRG(platform, sys_clk_freq, with_video_pll=with_video_framebuffer) + # SoCCore ---------------------------------------------------------------------------------- - SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on xem8320", **kwargs) + kwargs["uart_name"] = "jtag_uart" + SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on XEM8320", **kwargs) # DDR4 SDRAM ------------------------------------------------------------------------------- if not self.integrated_main_ram_size: - self.submodules.ddrphy = usddrphy.USPDDRPHY(platform.request("ddram"), + self.ddrphy = usddrphy.USPDDRPHY(platform.request("ddram"), memtype = "DDR4", sys_clk_freq = sys_clk_freq, iodelay_clk_freq = 500e6) @@ -90,7 +95,7 @@ class BaseSoC(SoCCore): # TODO: add SFP+ cages for ethernet # Ethernet / Etherbone --------------------------------------------------------------------- # if with_ethernet or with_etherbone: - # self.submodules.ethphy = KU_1000BASEX(self.crg.cd_eth.clk, + # self.ethphy = KU_1000BASEX(self.crg.cd_eth.clk, # data_pads = self.platform.request("sfp", 0), # sys_clk_freq = self.clk_freq) # self.comb += self.platform.request("sfp_tx_disable_n", 0).eq(1) @@ -100,48 +105,53 @@ class BaseSoC(SoCCore): # if with_etherbone: # self.add_etherbone(phy=self.ethphy, ip_address=eth_ip) - platform.add_extension(opalkelly_xem8320._dvi_pmod_io) - self.submodules.videophy = VideoDVIPHY(platform.request("dvi"), clock_domain="hdmi") - self.add_video_framebuffer(phy=self.videophy, timings="640x480@75Hz", clock_domain="hdmi") - + # Video ------------------------------------------------------------------------------------ + if with_video_framebuffer: + platform.add_extension(opalkelly_xem8320._dvi_pmod_io) + self.videophy = VideoDVIPHY(platform.request("dvi"), clock_domain="hdmi") + self.add_video_framebuffer(phy=self.videophy, timings="640x480@75Hz", clock_domain="hdmi") # Leds ------------------------------------------------------------------------------------- if with_led_chaser: - self.submodules.leds = LedChaser( + self.leds = LedChaser( pads = platform.request_all("user_led"), sys_clk_freq = sys_clk_freq) # Build -------------------------------------------------------------------------------------------- def main(): - from litex.soc.integration.soc import LiteXSoCArgumentParser - parser = LiteXSoCArgumentParser(description="LiteX SoC on XEM8320") - target_group = parser.add_argument_group(title="Target options") - target_group.add_argument("--build", action="store_true", help="Build design.") - target_group.add_argument("--load", action="store_true", help="Load bitstream.") - target_group.add_argument("--sys-clk-freq", default=125e6, help="System clock frequency.") - #ethopts = target_group.add_mutually_exclusive_group() - #ethopts.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support.") - builder_args(parser) - soc_core_args(parser) + from litex.build.parser import LiteXArgumentParser + parser = LiteXArgumentParser(platform=opalkelly_xem8320.Platform, description="LiteX SoC on XEM8320.") + parser.add_target_argument("--sys-clk-freq", default=125e6, type=float, help="System clock frequency.") + #ethopts = parser.target_group.add_mutually_exclusive_group() + #ethopts.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support.") + #ethopts.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support.") + #parser.add_target_argument("--eth-ip", default="192.168.1.50", help="Ethernet/Etherbone IP address.") + #parser.add_target_argument("--eth-dynamic-ip", action="store_true", help="Enable dynamic Ethernet IP addresses setting.") + viopts = parser.target_group.add_mutually_exclusive_group() + viopts.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal (HDMI).") + viopts.add_argument("--with-video-framebuffer", action="store_true", help="Enable Video Framebuffer (HDMI).") args = parser.parse_args() + #assert not (args.with_etherbone and args.eth_dynamic_ip) + soc = BaseSoC( - sys_clk_freq = int(float(args.sys_clk_freq)), - #with_ethernet = args.with_ethernet, - #with_etherbone = args.with_etherbone, - #eth_ip = args.eth_ip, - #with_pcie = args.with_pcie, - #with_sata = args.with_sata, - **soc_core_argdict(args) + sys_clk_freq = args.sys_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_video_terminal = args.with_video_terminal, + with_video_framebuffer = args.with_video_framebuffer, + **parser.soc_argdict ) soc.platform.add_extension(opalkelly_xem8320._sdcard_pmod_io) soc.add_spi_sdcard() - builder = Builder(soc, **builder_argdict(args)) + builder = Builder(soc, **parser.builder_argdict) if args.build: - builder.build() + builder.build(**parser.toolchain_argdict) if args.load: prog = soc.platform.create_programmer()