From bd95ce5e477e7eca1a233836c1de2ca3bcba80df Mon Sep 17 00:00:00 2001 From: Rakesh Peter Date: Tue, 11 Jan 2022 19:31:33 +0530 Subject: [PATCH 1/4] Create digilent_pynq_z1.py --- litex_boards/platforms/digilent_pynq_z1.py | 192 +++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 litex_boards/platforms/digilent_pynq_z1.py diff --git a/litex_boards/platforms/digilent_pynq_z1.py b/litex_boards/platforms/digilent_pynq_z1.py new file mode 100644 index 0000000..f25f6d7 --- /dev/null +++ b/litex_boards/platforms/digilent_pynq_z1.py @@ -0,0 +1,192 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2019-2020 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform, VivadoProgrammer + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # Clk / Rst + ("sysclk", 0, Pins("H16"), IOStandard("LVCMOS33")), + + # Leds + ("user_led", 0, Pins("R14"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("P14"), IOStandard("LVCMOS33")), + ("user_led", 2, Pins("N16"), IOStandard("LVCMOS33")), + ("user_led", 3, Pins("M14"), IOStandard("LVCMOS33")), + ("user_led", 4, Pins("L15"), IOStandard("LVCMOS33")), + ("user_led", 5, Pins("G17"), IOStandard("LVCMOS33")), + ("user_led", 6, Pins("N15"), IOStandard("LVCMOS33")), + ("user_led", 7, Pins("G14"), IOStandard("LVCMOS33")), + ("user_led", 8, Pins("L14"), IOStandard("LVCMOS33")), + ("user_led", 9, Pins("M15"), IOStandard("LVCMOS33")), + + # Switches + ("user_sw", 0, Pins("M20"), IOStandard("LVCMOS33")), + ("user_sw", 1, Pins("M19"), IOStandard("LVCMOS33")), + + # Buttons + ("user_btn", 0, Pins("D19"), IOStandard("LVCMOS33")), + ("user_btn", 1, Pins("D20"), IOStandard("LVCMOS33")), + ("user_btn", 2, Pins("L20"), IOStandard("LVCMOS33")), + ("user_btn", 3, Pins("L19"), IOStandard("LVCMOS33")), + + #Serial + ("serial", 0, + Subsignal("tx", Pins("pmoda:1")), + Subsignal("rx", Pins("pmoda:2")), + IOStandard("LVCMOS33") + ), + + # Audio + ("aud_pwm", 0, Pins("R18"), IOStandard("LVCMOS33")), + ("aud_sd", 0, Pins("T17"), IOStandard("LVCMOS33")), + ("m_clk", 0, Pins("F17"), IOStandard("LVCMOS33")), + ("m_data", 0, Pins("G18"), IOStandard("LVCMOS33")), + + # Chipkit Single Ended Analog Input + ("ck_an_n", 0, Pins("D18"), IOStandard("LVCMOS33")), + ("ck_an_p", 0, Pins("E17"), IOStandard("LVCMOS33")), + ("ck_an_n", 1, Pins("E19"), IOStandard("LVCMOS33")), + ("ck_an_p", 1, Pins("E18"), IOStandard("LVCMOS33")), + ("ck_an_n", 2, Pins("J14"), IOStandard("LVCMOS33")), + ("ck_an_p", 2, Pins("K14"), IOStandard("LVCMOS33")), + ("ck_an_n", 3, Pins("J16"), IOStandard("LVCMOS33")), + ("ck_an_p", 3, Pins("K16"), IOStandard("LVCMOS33")), + ("ck_an_n", 4, Pins("H20"), IOStandard("LVCMOS33")), + ("ck_an_p", 4, Pins("J20"), IOStandard("LVCMOS33")), + ("ck_an_n", 5, Pins("G20"), IOStandard("LVCMOS33")), + ("ck_an_p", 5, Pins("G19"), IOStandard("LVCMOS33")), + + # Chipkit SPI + ("ck_miso", 0, Pins("W15"), IOStandard("LVCMOS33")), + ("ck_mosi", 0, Pins("T12"), IOStandard("LVCMOS33")), + ("ck_sck", 0, Pins("H15"), IOStandard("LVCMOS33")), + ("ck_ss", 0, Pins("F16"), IOStandard("LVCMOS33")), + + # Chipkit I2C + ("ck_scl", 0, Pins("P16"), IOStandard("LVCMOS33")), + ("ck_sda", 0, Pins("P15"), IOStandard("LVCMOS33")), + + # Crypto SDA + ("crypto_sda", 0, Pins("J15"), IOStandard("LVCMOS33")) + +] + +_ps7_io = [ + # PS7 + ("ps7_clk", 0, Pins("E7")), + ("ps7_porb", 0, Pins("C7")), + ("ps7_srstb", 0, Pins("B10")), + ("ps7_mio", 0, Pins( + "E6 A7 B8 D6 B7 A6 A5 D8", + "D5 B5 E9 C6 D9 E8 C5 C8", + "A19 E14 B18 D10 A17 F14 B17 D11", + "A16 F15 A15 D13 C16 C13 C15 E16", + "A14 D15 A12 F12 A11 A10 E13 C18" + "D14 C17 E12 A9 F13 B15 D16 B14" + "B12 C12 B13 B9 C10 C11")), + ("ps7_ddram", 0, + Subsignal("addr", Pins( + "N2 K2 M3 K3 M4 L1 L4 K4", + "K1 J4 F5 G4 E4 D4 F4")), + Subsignal("ba", Pins("L5 R4 J5")), + Subsignal("cas_n", Pins("P5")), + Subsignal("cke", Pins("N3")), + Subsignal("ck_n", Pins("M2")), + Subsignal("ck_p", Pins("L2")), + Subsignal("cs_n", Pins("N1")), + Subsignal("dm", Pins("A1 F1 T1 Y1")), + Subsignal("dq", Pins( + " C3 B3 A2 A4 D3 D1 C1 E1", + " E2 E3 G3 H3 J3 H2 H1 J1", + " P1 P3 R3 R1 T4 U4 U2 U3", + " V1 Y3 W1 Y4 Y2 W3 V2 V3"), + ), + Subsignal("dqs_n", Pins("B2 F2 T2 W4")), + Subsignal("dqs_p", Pins("C2 G2 R2 W5")), + Subsignal("reset_n", Pins("B4")), + Subsignal("odt", Pins("N5")), + Subsignal("ras_n", Pins("P4")), + Subsignal("vrn", Pins("G5")), + Subsignal("vrp", Pins("H5")), + Subsignal("we_n", Pins("M5")) + ), +] + +_usb_uart_pmod_io = [ + # USB-UART PMOD on JB: + # - https://store.digilentinc.com/pmod-usbuart-usb-to-uart-interface/ + ("usb_uart", 0, + Subsignal("tx", Pins("pmodb:1")), + Subsignal("rx", Pins("pmodb:2")), + IOStandard("LVCMOS33") + ), +] + +_hdmi_rx_io = [ + # HDMI Rx + ("hdmi_rx", 0, + Subsignal("cec", Pins("H17"), IOStandard("LVCMOS33")), + Subsignal("clk_p", Pins("N18"), IOStandard("TMDS_33")), + Subsignal("clk_n", Pins("P19"), IOStandard("TMDS_33")), + Subsignal("data0_p", Pins("V20"), IOStandard("TMDS_33")), + Subsignal("data0_n", Pins("W20"), IOStandard("TMDS_33")), + Subsignal("data1_p", Pins("T20"), IOStandard("TMDS_33")), + Subsignal("data1_n", Pins("U20"), IOStandard("TMDS_33")), + Subsignal("data2_p", Pins("N20"), IOStandard("TMDS_33")), + Subsignal("data2_n", Pins("P20"), IOStandard("TMDS_33")), + Subsignal("hpd", Pins("T19"), IOStandard("LVCMOS33")), + Subsignal("scl", Pins("U14"), IOStandard("LVCMOS33")), + Subsignal("sda", Pins("U15"), IOStandard("LVCMOS33")), + ), +] + +_hdmi_tx_io = [ + # HDMI Tx + ("hdmi_tx", 0, + Subsignal("cec", Pins("G15"), IOStandard("LVCMOS33")), + Subsignal("clk_p", Pins("L16"), IOStandard("TMDS_33")), + Subsignal("clk_n", Pins("L17"), IOStandard("TMDS_33")), + Subsignal("data0_p", Pins("K17"), IOStandard("TMDS_33")), + Subsignal("data0_n", Pins("K18"), IOStandard("TMDS_33")), + Subsignal("data1_p", Pins("K19"), IOStandard("TMDS_33")), + Subsignal("data1_n", Pins("J19"), IOStandard("TMDS_33")), + Subsignal("data2_p", Pins("J18"), IOStandard("TMDS_33")), + Subsignal("data2_n", Pins("H18"), IOStandard("TMDS_33")), + Subsignal("hpdn", Pins("R19"), IOStandard("LVCMOS33")), + Subsignal("scl", Pins("M17"), IOStandard("LVCMOS33")), + Subsignal("sda", Pins("M18"), IOStandard("LVCMOS33")), + ), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + ("pmoda", "Y18 Y19 Y16 Y17 U18 U19 W18 W19"), # XADC + ("pmodb", "W14 Y14 T11 T10 V16 W16 V12 W13"), + ("ck_io", "T14 U12 U13 V13 V15 T15 R16 U17 V17 V18 T16 R17 P18 N17 Y11 Y12 W11 V11 T5 U10 B20 C20 F20 F19 A20 B19 U5 V5 V6 U7 V7 U8 V8 V10 W10 W6 Y6 Y7 W8 Y8 W9 Y9 Y13") +] +# Platform ----------------------------------------------------------------------------------------- + +class Platform(XilinxPlatform): + default_clk_name = "sysclk" + default_clk_period = 1e9/125e6 + + def __init__(self): + XilinxPlatform.__init__(self, "xc7z020-clg400-1", _io, _connectors, toolchain="vivado") + self.add_extension(_ps7_io) + self.add_extension(_usb_uart_pmod_io) + self.add_extension(_hdmi_rx_io) + self.add_extension(_hdmi_tx_io) + + def create_programmer(self): + return VivadoProgrammer() + + def do_finalize(self, fragment): + XilinxPlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("sysclk", loose=True), 1e9/125e6) From ed50c84e0dc582b976d9247f46b11a4d9c55facf Mon Sep 17 00:00:00 2001 From: Rakesh Peter Date: Tue, 11 Jan 2022 19:33:12 +0530 Subject: [PATCH 2/4] Support for Digilent Pynq Z1 --- litex_boards/targets/digilent_pynq_z1.py | 107 +++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 litex_boards/targets/digilent_pynq_z1.py diff --git a/litex_boards/targets/digilent_pynq_z1.py b/litex_boards/targets/digilent_pynq_z1.py new file mode 100644 index 0000000..750f135 --- /dev/null +++ b/litex_boards/targets/digilent_pynq_z1.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2019-2020 Florent Kermarrec , +# SPDX-License-Identifier: BSD-2-Clause + +import os +import argparse + +from migen import * + +from litex_boards.platforms import pynq_z1 +from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict + +from litex.soc.interconnect import axi +from litex.soc.interconnect import wishbone + +from litex.soc.cores.clock import * + +from litex.soc.integration.soc_core import * +from litex.soc.integration.builder import * +from litex.soc.cores.led import LedChaser + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq, use_ps7_clk=False): + self.rst = Signal() + self.clock_domains.cd_sys = ClockDomain() + + # # # + + if use_ps7_clk: + assert sys_clk_freq == 125e6 + self.comb += ClockSignal("sys").eq(ClockSignal("ps7")) + self.comb += ResetSignal("sys").eq(ResetSignal("ps7") | self.rst) + else: + self.submodules.pll = pll = S7PLL(speedgrade=-1) + self.comb += pll.reset.eq(self.rst) + pll.register_clkin(platform.request("sysclk"), 125e6) + pll.create_clkout(self.cd_sys, 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. + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=int(100e6), with_led_chaser=True, **kwargs): + platform = pynq_z1.Platform() + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on PYNQ Z1", + ident_version = True, + **kwargs) + + # Zynq7000 Integration --------------------------------------------------------------------- + if kwargs.get("cpu_type", None) == "zynq7000": + # Get and set the pre-generated .xci FIXME: change location? add it to the repository? + os.system("wget https://github.com/litex-hub/litex-boards/files/4967144/zybo_z7_ps7.txt") + os.makedirs("xci", exist_ok=True) + os.system("mv zybo_z7_ps7.txt xci/zybo_z7_ps7.xci") + self.cpu.set_ps7_xci("xci/zybo_z7_ps7.xci") + + # Connect AXI GP0 to the SoC with base address of 0x43c00000 (default one) + wb_gp0 = wishbone.Interface() + self.submodules += axi.AXI2Wishbone( + axi = self.cpu.add_axi_gp_master(), + wishbone = wb_gp0, + base_address = 0x43c00000) + self.add_wb_master(wb_gp0) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # Leds ------------------------------------------------------------------------------------- + if with_led_chaser: + self.submodules.leds = LedChaser( + pads = platform.request_all("user_led"), + sys_clk_freq = sys_clk_freq) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on PYNQ Z1") + parser.add_argument("--build", action="store_true", help="Build bitstream") + parser.add_argument("--load", action="store_true", help="Load bitstream") + parser.add_argument("--sys-clk-freq", default=125e6, help="System clock frequency (default: 100MHz)") + builder_args(parser) + soc_core_args(parser) + vivado_build_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + sys_clk_freq = int(float(args.sys_clk_freq)), + **soc_core_argdict(args) + ) + builder = Builder(soc, **builder_argdict(args)) + builder.build(**vivado_build_argdict(args), run=args.build) + + if args.load: + prog = soc.platform.create_programmer() + prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bit"), device=1) + +if __name__ == "__main__": + main() From e489c3e3deb8acffd144a71b889bc29f0b158144 Mon Sep 17 00:00:00 2001 From: Rakesh Peter Date: Thu, 13 Jan 2022 23:24:50 +0530 Subject: [PATCH 3/4] Change Serial port to pmoda:0/1 Remove usb_uart. Copyright notice update. --- litex_boards/platforms/digilent_pynq_z1.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/litex_boards/platforms/digilent_pynq_z1.py b/litex_boards/platforms/digilent_pynq_z1.py index f25f6d7..558e3ee 100644 --- a/litex_boards/platforms/digilent_pynq_z1.py +++ b/litex_boards/platforms/digilent_pynq_z1.py @@ -1,7 +1,7 @@ # # This file is part of LiteX-Boards. # -# Copyright (c) 2019-2020 Florent Kermarrec +# Copyright (c) 2022 Rakesh Peter # SPDX-License-Identifier: BSD-2-Clause from litex.build.generic_platform import * @@ -10,7 +10,7 @@ from litex.build.xilinx import XilinxPlatform, VivadoProgrammer # IOs ---------------------------------------------------------------------------------------------- _io = [ - # Clk / Rst + # Clk ("sysclk", 0, Pins("H16"), IOStandard("LVCMOS33")), # Leds @@ -37,8 +37,8 @@ _io = [ #Serial ("serial", 0, - Subsignal("tx", Pins("pmoda:1")), - Subsignal("rx", Pins("pmoda:2")), + Subsignal("tx", Pins("pmoda:0")), + Subsignal("rx", Pins("pmoda:1")), IOStandard("LVCMOS33") ), @@ -118,16 +118,6 @@ _ps7_io = [ ), ] -_usb_uart_pmod_io = [ - # USB-UART PMOD on JB: - # - https://store.digilentinc.com/pmod-usbuart-usb-to-uart-interface/ - ("usb_uart", 0, - Subsignal("tx", Pins("pmodb:1")), - Subsignal("rx", Pins("pmodb:2")), - IOStandard("LVCMOS33") - ), -] - _hdmi_rx_io = [ # HDMI Rx ("hdmi_rx", 0, @@ -180,7 +170,6 @@ class Platform(XilinxPlatform): def __init__(self): XilinxPlatform.__init__(self, "xc7z020-clg400-1", _io, _connectors, toolchain="vivado") self.add_extension(_ps7_io) - self.add_extension(_usb_uart_pmod_io) self.add_extension(_hdmi_rx_io) self.add_extension(_hdmi_tx_io) From a3d168e4c073928d52f41092fa28bcbd6af84eba Mon Sep 17 00:00:00 2001 From: Rakesh Peter Date: Thu, 13 Jan 2022 23:28:43 +0530 Subject: [PATCH 4/4] HDMI Terminal Support Copyright notice update. --- litex_boards/targets/digilent_pynq_z1.py | 51 +++++++++++++++++------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/litex_boards/targets/digilent_pynq_z1.py b/litex_boards/targets/digilent_pynq_z1.py index 750f135..add8416 100644 --- a/litex_boards/targets/digilent_pynq_z1.py +++ b/litex_boards/targets/digilent_pynq_z1.py @@ -3,7 +3,7 @@ # # This file is part of LiteX-Boards. # -# Copyright (c) 2019-2020 Florent Kermarrec , +# Copyright (c) 2022 Rakesh Peter # SPDX-License-Identifier: BSD-2-Clause import os @@ -17,21 +17,27 @@ from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict from litex.soc.interconnect import axi from litex.soc.interconnect import wishbone -from litex.soc.cores.clock import * - from litex.soc.integration.soc_core import * from litex.soc.integration.builder import * + +from litex.soc.cores.clock import * +from litex.soc.cores.video import VideoS7HDMIPHY from litex.soc.cores.led import LedChaser # CRG ---------------------------------------------------------------------------------------------- - class _CRG(Module): - def __init__(self, platform, sys_clk_freq, use_ps7_clk=False): + def __init__(self, platform, sys_clk_freq, toolchain, use_ps7_clk=False, with_video_pll=False): self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_hdmi = ClockDomain() + self.clock_domains.cd_hdmi5x = ClockDomain() # # # + # Clk + clk125 = platform.request("sysclk") + + # PLL if use_ps7_clk: assert sys_clk_freq == 125e6 self.comb += ClockSignal("sys").eq(ClockSignal("ps7")) @@ -39,14 +45,23 @@ class _CRG(Module): else: self.submodules.pll = pll = S7PLL(speedgrade=-1) self.comb += pll.reset.eq(self.rst) - pll.register_clkin(platform.request("sysclk"), 125e6) + pll.register_clkin(clk125, 125e6) pll.create_clkout(self.cd_sys, 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. + # Video PLL. + if with_video_pll: + self.submodules.video_pll = video_pll = S7MMCM(speedgrade=-1) + video_pll.reset.eq(self.rst) + video_pll.register_clkin(clk125, 125e6) + 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), with_led_chaser=True, **kwargs): + def __init__(self, toolchain="vivado", sys_clk_freq=int(100e6), with_led_chaser=True, + with_video_terminal=False, with_video_framebuffer=False, **kwargs): platform = pynq_z1.Platform() # SoCCore ---------------------------------------------------------------------------------- @@ -62,7 +77,7 @@ class BaseSoC(SoCCore): os.makedirs("xci", exist_ok=True) os.system("mv zybo_z7_ps7.txt xci/zybo_z7_ps7.xci") self.cpu.set_ps7_xci("xci/zybo_z7_ps7.xci") - + # Connect AXI GP0 to the SoC with base address of 0x43c00000 (default one) wb_gp0 = wishbone.Interface() self.submodules += axi.AXI2Wishbone( @@ -72,8 +87,13 @@ class BaseSoC(SoCCore): self.add_wb_master(wb_gp0) # CRG -------------------------------------------------------------------------------------- - self.submodules.crg = _CRG(platform, sys_clk_freq) - + self.submodules.crg = _CRG(platform, sys_clk_freq, toolchain, with_video_pll=with_video_terminal) + + # Video ------------------------------------------------------------------------------------ + if with_video_terminal: + self.submodules.videophy = VideoS7HDMIPHY(platform.request("hdmi_tx"), clock_domain="hdmi") + self.add_video_terminal(phy=self.videophy, timings="800x600@60Hz", clock_domain="hdmi") + # Leds ------------------------------------------------------------------------------------- if with_led_chaser: self.submodules.leds = LedChaser( @@ -84,9 +104,11 @@ class BaseSoC(SoCCore): def main(): parser = argparse.ArgumentParser(description="LiteX SoC on PYNQ Z1") - parser.add_argument("--build", action="store_true", help="Build bitstream") - parser.add_argument("--load", action="store_true", help="Load bitstream") - parser.add_argument("--sys-clk-freq", default=125e6, help="System clock frequency (default: 100MHz)") + parser.add_argument("--build", action="store_true", help="Build bitstream") + parser.add_argument("--load", action="store_true", help="Load bitstream") + parser.add_argument("--sys-clk-freq", default=125e6, help="System clock frequency (default: 125MHz)") + parser.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal (HDMI)") + builder_args(parser) soc_core_args(parser) vivado_build_args(parser) @@ -94,7 +116,8 @@ def main(): soc = BaseSoC( sys_clk_freq = int(float(args.sys_clk_freq)), - **soc_core_argdict(args) + with_video_terminal = args.with_video_terminal, + **soc_core_argdict(args) ) builder = Builder(soc, **builder_argdict(args)) builder.build(**vivado_build_argdict(args), run=args.build)