diff --git a/litex_boards/platforms/redpitaya.py b/litex_boards/platforms/redpitaya.py new file mode 100644 index 0000000..2356b03 --- /dev/null +++ b/litex_boards/platforms/redpitaya.py @@ -0,0 +1,167 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2020 Gwenhael Goavec-Merou +# SPDX-License-Identifier: BSD-2-Clause + +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform, VivadoProgrammer + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # Leds + ("user_led", 0, Pins("F16"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("F17"), IOStandard("LVCMOS33")), + ("user_led", 2, Pins("G15"), IOStandard("LVCMOS33")), + ("user_led", 3, Pins("H15"), IOStandard("LVCMOS33")), + ("user_led", 4, Pins("K14"), IOStandard("LVCMOS33")), + ("user_led", 5, Pins("G14"), IOStandard("LVCMOS33")), + ("user_led", 6, Pins("J15"), IOStandard("LVCMOS33")), + ("user_led", 7, Pins("J14"), IOStandard("LVCMOS33")), + + ("dac", 0, + Subsignal("data", + Pins("M19 M20 L19 L20 K19 J19 K20 H20 G19 G20 F19 F20 D20 D19"), + Drive(4), Misc("SLEW SLOW")), + Subsignal("wrt", Pins("M17"), Drive(8), Misc("SLEW FAST")), + Subsignal("sel", Pins("N16"), Drive(8), Misc("SLEW FAST")), + Subsignal("clk", Pins("M18"), Drive(8), Misc("SLEW FAST")), + Subsignal("rst", Pins("N15"), Drive(8), Misc("SLEW FAST")), + IOStandard("LVCMOS33"), + ), + + ("pwm_dac", 0, Pins("T10"), IOStandard("LVCMOS18"), + Drive(8), Misc("SLEW FAST")), + ("pwm_dac", 1, Pins("T11"), IOStandard("LVCMOS18"), + Drive(8), Misc("SLEW FAST")), + ("pwm_dac", 2, Pins("P15"), IOStandard("LVCMOS18"), + Drive(8), Misc("SLEW FAST")), + ("pwm_dac", 3, Pins("U13"), IOStandard("LVCMOS18"), + Drive(8), Misc("SLEW FAST")), + + ("daisy", 0, + Subsignal("io0_p", Pins("T12")), + Subsignal("io0_n", Pins("U12")), + Subsignal("io1_p", Pins("U14")), + Subsignal("io1_n", Pins("U15")), + IOStandard("DIFF_HSTL_I_18"), + ), + + ("daisy", 1, + Subsignal("io0_p", Pins("P14")), + Subsignal("io0_n", Pins("R14")), + Subsignal("io1_p", Pins("N18")), + Subsignal("io1_n", Pins("P19")), + IOStandard("DIFF_HSTL_I_18"), + ), + +] + +_io_14 = [ + # Clk / Rst + ("clk125", 0, + Subsignal("p", Pins("U18")), + Subsignal("n", Pins("U19")), + IOStandard("DIFF_HSTL_I_18"), + ), + + ("adc", 0, + Subsignal("data_a", + Pins("Y17 W16 Y16 W15 W14 Y14 W13 V12 V13 T14 T15 V15 T16 V16")), + Subsignal("data_b", + Pins("R18 P16 P18 N17 R19 T20 T19 U20 V20 W20 W19 Y19 W18 Y18")), + Subsignal("cdcs", Pins("V18")), + IOStandard("LVCMOS18"), + ), +] + +_io_16 = [ + # Clk / Rst + ("clk122", 0, + Subsignal("p", Pins("U18")), + Subsignal("n", Pins("U19")), + IOStandard("DIFF_HSTL_I_18"), + ), + + ("adc", 0, + Subsignal("data_a", + Pins("V17 U17 Y17 W16 Y16 W15 W14 Y14 W13 V12 V13 T14 T15 V15 T16 V16")), + Subsignal("data_b", + Pins("T17 R16 R18 P16 P18 N17 R19 T20 T19 U20 V20 W20 W19 Y19 W18 Y18")), + Subsignal("cdcs", Pins("V18")), + IOStandard("LVCMOS18"), + ), +] + +_ps7_io = [ + # PS7 + ("ps7_clk", 0, Pins(1)), + ("ps7_porb", 0, Pins(1)), + ("ps7_srstb", 0, Pins(1)), + ("ps7_mio", 0, Pins(54)), + ("ps7_ddram", 0, + Subsignal("addr", Pins(15)), + Subsignal("ba", Pins(3)), + Subsignal("cas_n", Pins(1)), + Subsignal("ck_n", Pins(1)), + Subsignal("ck_p", Pins(1)), + Subsignal("cke", Pins(1)), + Subsignal("cs_n", Pins(1)), + Subsignal("dm", Pins(4)), + Subsignal("dq", Pins(32)), + Subsignal("dqs_n", Pins(4)), + Subsignal("dqs_p", Pins(4)), + Subsignal("odt", Pins(1)), + Subsignal("ras_n", Pins(1)), + Subsignal("reset_n", Pins(1)), + Subsignal("we_n", Pins(1)), + Subsignal("vrn", Pins(1)), + Subsignal("vrp", Pins(1)), + ), +] + +_uart_io = [ + ("usb_uart", 0, + Subsignal("tx", Pins("E1:3")), + Subsignal("rx", Pins("E1:4")), + IOStandard("LVCMOS33") + ), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + ("E1", "- - G17 G18 H16 H17 J18 H18 K17 K18 L14 L15 L16 L17 K16 J16 M14 M15 - - - - - - - -"), +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(XilinxPlatform): + + def __init__(self, board="redpitaya14"): + if board == "redpitaya14": + device = "xc7z010clg400-1" + extension = _io_14 + self.default_clk_name = "clk125" + self.default_clk_freq = 125e6 + else: + device = "xc7z020clg400-1" + extension = _io_16 + self.default_clk_name = "clk122" + self.default_clk_freq = 122e6 + + self.default_clk_period = 1e9/self.default_clk_freq + + XilinxPlatform.__init__(self, device, _io, _connectors, toolchain="vivado") + self.add_extension(extension) + self.add_extension(_ps7_io) + self.add_extension(_uart_io) + + def create_programmer(self): + return VivadoProgrammer() + + def do_finalize(self, fragment): + XilinxPlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request(self.default_clk_name, loose=True), + self.default_clk_period) diff --git a/litex_boards/targets/redpitaya.py b/litex_boards/targets/redpitaya.py new file mode 100755 index 0000000..6908d46 --- /dev/null +++ b/litex_boards/targets/redpitaya.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2020 Gwenhael Goavec-Merou +# SPDX-License-Identifier: BSD-2-Clause + +import os +import argparse + +from migen import * + +from litex_boards.platforms import redpitaya +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(platform.default_clk_name), platform.default_clk_freq) + pll.create_clkout(self.cd_sys, sys_clk_freq) + +# BaseSoC ------------------------------------------------------------------------------------------ + + +class BaseSoC(SoCCore): + def __init__(self, board, sys_clk_freq=int(100e6), **kwargs): + platform = redpitaya.Platform(board) + + if kwargs["uart_name"] == "serial": + kwargs["uart_name"] = "usb_uart" + + use_ps7_clk = False + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on Zebboard", + 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://kmf2.trabucayre.com/redpitaya_ps7.txt") + os.makedirs("xci", exist_ok=True) + os.system("cp redpitaya_ps7.txt xci/redpitaya_ps7.xci") + self.cpu.set_ps7_xci("xci/redpitaya_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) + use_ps7_clk = True + sys_clk_freq = 125e6 + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq, use_ps7_clk) + + # Leds ------------------------------------------------------------------------------------- + self.submodules.leds = LedChaser( + pads = platform.request_all("user_led"), + sys_clk_freq = sys_clk_freq) + self.add_csr("leds") + +# Build -------------------------------------------------------------------------------------------- + + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on Zedboard") + 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=100e6, help="System clock frequency (default: 100MHz)") + parser.add_argument("--board", default="redpitaya14", help="Board type: redpitaya14 (default) or redpitaya16") + builder_args(parser) + soc_core_args(parser) + vivado_build_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + board = args.board, + 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()