From ce5b2a74a1a59c4659bfeefc72674fd8d14872fe Mon Sep 17 00:00:00 2001 From: helium729 Date: Mon, 17 May 2021 16:39:16 +0800 Subject: [PATCH] add digilent basys3 support --- litex_boards/platforms/digilent_basys3.py | 132 ++++++++++++++++++++++ litex_boards/targets/digilent_basys3.py | 116 +++++++++++++++++++ test/test_targets.py | 1 + 3 files changed, 249 insertions(+) create mode 100644 litex_boards/platforms/digilent_basys3.py create mode 100644 litex_boards/targets/digilent_basys3.py diff --git a/litex_boards/platforms/digilent_basys3.py b/litex_boards/platforms/digilent_basys3.py new file mode 100644 index 0000000..12249c9 --- /dev/null +++ b/litex_boards/platforms/digilent_basys3.py @@ -0,0 +1,132 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2020-2021 Xuanyu Hu +# SPDX-License-Identifier: BSD-2-Clause + +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform, VivadoProgrammer +from litex.build.openocd import OpenOCD + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # Clk / Rst + ("clk100", 0, Pins("W3"), IOStandard("LVCMOS33")), + + # Leds + ("user_led", 0, Pins("U16"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("E19"), IOStandard("LVCMOS33")), + ("user_led", 2, Pins("U19"), IOStandard("LVCMOS33")), + ("user_led", 3, Pins("V19"), IOStandard("LVCMOS33")), + ("user_led", 4, Pins("W18"), IOStandard("LVCMOS33")), + ("user_led", 5, Pins("U15"), IOStandard("LVCMOS33")), + ("user_led", 6, Pins("U14"), IOStandard("LVCMOS33")), + ("user_led", 7, Pins("V14"), IOStandard("LVCMOS33")), + ("user_led", 8, Pins("V13"), IOStandard("LVCMOS33")), + ("user_led", 9, Pins("V3"), IOStandard("LVCMOS33")), + ("user_led", 10, Pins("W3"), IOStandard("LVCMOS33")), + ("user_led", 11, Pins("U3"), IOStandard("LVCMOS33")), + ("user_led", 12, Pins("P3"), IOStandard("LVCMOS33")), + ("user_led", 13, Pins("N3"), IOStandard("LVCMOS33")), + ("user_led", 14, Pins("P1"), IOStandard("LVCMOS33")), + ("user_led", 15, Pins("L1"), IOStandard("LVCMOS33")), + + # Switches + ("user_sw", 0, Pins("V17"), IOStandard("LVCMOS33")), + ("user_sw", 1, Pins("V16"), IOStandard("LVCMOS33")), + ("user_sw", 2, Pins("W16"), IOStandard("LVCMOS33")), + ("user_sw", 3, Pins("W17"), IOStandard("LVCMOS33")), + ("user_sw", 4, Pins("W15"), IOStandard("LVCMOS33")), + ("user_sw", 5, Pins("V15"), IOStandard("LVCMOS33")), + ("user_sw", 6, Pins("W14"), IOStandard("LVCMOS33")), + ("user_sw", 7, Pins("W13"), IOStandard("LVCMOS33")), + ("user_sw", 8, Pins("V2"), IOStandard("LVCMOS33")), + ("user_sw", 9, Pins("T3"), IOStandard("LVCMOS33")), + ("user_sw", 10, Pins("T2"), IOStandard("LVCMOS33")), + ("user_sw", 11, Pins("R3"), IOStandard("LVCMOS33")), + ("user_sw", 12, Pins("W2"), IOStandard("LVCMOS33")), + ("user_sw", 13, Pins("U1"), IOStandard("LVCMOS33")), + ("user_sw", 14, Pins("T1"), IOStandard("LVCMOS33")), + ("user_sw", 15, Pins("R2"), IOStandard("LVCMOS33")), + + # Buttons + ("user_btnu", 0, Pins("T18"), IOStandard("LVCMOS33")), + ("user_btnd", 0, Pins("U17"), IOStandard("LVCMOS33")), + ("user_btnl", 0, Pins("W19"), IOStandard("LVCMOS33")), + ("user_btnr", 0, Pins("T17"), IOStandard("LVCMOS33")), + ("user_btnc", 0, Pins("U18"), IOStandard("LVCMOS33")), + + # Serial + ("serial", 0, + Subsignal("tx", Pins("A18")), + Subsignal("rx", Pins("B18")), + IOStandard("LVCMOS33"), + ), + + # VGA + ("vga", 0, + Subsignal("hsync_n", Pins("P19")), + Subsignal("vsync_n", Pins("R18")), + Subsignal("r", Pins("G19 H19 J19 N19")), + Subsignal("g", Pins("J17 H17 G17 D17")), + Subsignal("b", Pins("N18 L18 K18 J18")), + IOStandard("LVCMOS33") + ), + + # USB PS/2 + ("usbhost", 0, + Subsignal("ps2_clk", Pins("B6")), + Subsignal("ps2_data", Pins("A6")), + IOStandard("LVCMOS33")) + +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + ("pmoda", "J1 L2 J2 G2 H1 K2 H2 G3"), + ("pmodb", "A14 A16 B15 B16 A15 A17 C15 C16"), + ("pmodc", "K17 M18 N17 P18 L17 M19 P17 R18"), + ("pmodxdac", "J3 L3 M2 N2 K3 M3 M1 N1"), +] + +# PMODS -------------------------------------------------------------------------------------------- + +def sdcard_pmod_io(pmod): + return [ + # SDCard PMOD: + # - https://store.digilentinc.com/pmod-microsd-microsd-card-slot/ + ("spisdcard", 0, + Subsignal("clk", Pins(f"{pmod}:3")), + Subsignal("mosi", Pins(f"{pmod}:1"), Misc("PULLUP True")), + Subsignal("cs_n", Pins(f"{pmod}:0"), Misc("PULLUP True")), + Subsignal("miso", Pins(f"{pmod}:2"), Misc("PULLUP True")), + Misc("SLEW=FAST"), + IOStandard("LVCMOS33"), + ), + ("sdcard", 0, + Subsignal("data", Pins(f"{pmod}:2 {pmod}:4 {pmod}:5 {pmod}:0"), Misc("PULLUP True")), + Subsignal("cmd", Pins(f"{pmod}:1"), Misc("PULLUP True")), + Subsignal("clk", Pins(f"{pmod}:3")), + Subsignal("cd", Pins(f"{pmod}:6")), + Misc("SLEW=FAST"), + IOStandard("LVCMOS33"), + ), + +] +_sdcard_pmod_io = sdcard_pmod_io("pmoda") # SDCARD PMOD on JD. + +class Platform(XilinxPlatform): + default_clk_name = "clk100" + default_clk_period = 1e9/100e6 + + def __init__(self): + XilinxPlatform.__init__(self, "xc7a35t-CPG236-1", _io, _connectors, toolchain="vivado") + + def create_programmer(self): + return OpenOCD("openocd_xc7_ft2232.cfg", "bscan_spi_xc7a35t.bit") + + def do_finalize(self, fragment): + XilinxPlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("clk100", loose=True), 1e9/100e6) diff --git a/litex_boards/targets/digilent_basys3.py b/litex_boards/targets/digilent_basys3.py new file mode 100644 index 0000000..32b6c0c --- /dev/null +++ b/litex_boards/targets/digilent_basys3.py @@ -0,0 +1,116 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2020-2021 Xuanyu Hu +# SPDX-License-Identifier: BSD-2-Clause + +import os +import argparse +from litex.build.xilinx import platform + +from migen import * + +from litex_boards.platforms import basys3 + +from litex.soc.cores.clock import * +from litex.soc.integration.soc import SoCRegion +from litex.soc.integration.soc_core import * +from litex.soc.integration.builder import * +from litex.soc.cores.video import VideoVGAPHY +from litex.soc.cores.led import LedChaser + +from litedram.modules import MT47H64M16 +from litedram.phy import s7ddrphy + +from liteeth.phy.rmii import LiteEthPHYRMII + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.rst = Signal() + self.clock_domains.cd_sys = ClockDomain() + 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_vga = ClockDomain(reset_less=True) + + self.submodules.pll = pll = S7MMCM(speedgrade=-1) + self.comb += pll.reset.eq(~platform.request("user_btnc") | self.rst) + + pll.register_clkin(platform.request("clk100"), 100e6) + pll.create_clkout(self.cd_sys, sys_clk_freq) + pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq) + pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90) + pll.create_clkout(self.cd_idelay, 200e6) + pll.create_clkout(self.cd_vga, 40e6) + platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) + + self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay) + +# BaseSoC ------------------------------------------------------------------------------------------ +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=int(75e6), with_video_terminal=False, with_video_framebuffer=False, **kwargs): + platform = basys3.Platform() + + # SoCCore ----------------------------------_----------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on Basys3", + ident_version = True, + **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + if with_video_terminal or with_video_framebuffer: + self.submodules.videophy = VideoVGAPHY(platform.request("vga"), clock_domain="vga") + if with_video_terminal: + self.add_video_terminal(phy=self.videophy, timings="800x600@60Hz", clock_domain="vga") + if with_video_framebuffer: + self.add_video_framebuffer(phy=self.videophy, timings="800x600@60Hz", clock_domain="vga") + + 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 Basys3") + 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=75e6, help="System clock frequency (default: 75MHz)") + sdopts = parser.add_mutually_exclusive_group() + sdopts.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support") + sdopts.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support") + parser.add_argument("--sdcard-adapter", type=str, help="SDCard PMOD adapter: digilent (default) or numato") + viopts = parser.add_mutually_exclusive_group() + viopts.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal (VGA)") + viopts.add_argument("--with-video-framebuffer", action="store_true", help="Enable Video Framebuffer (VGA)") + builder_args(parser) + soc_core_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + sys_clk_freq = int(float(args.sys_clk_freq)), + with_video_terminal = args.with_video_terminal, + with_video_framebuffer = args.with_video_framebuffer, + **soc_core_argdict(args) + ) + soc.platform.add_extension(basys3._sdcard_pmod_io) + if args.with_spi_sdcard: + soc.add_spi_sdcard() + if args.with_sdcard: + soc.add_sdcard() + if args.with_spi_sdcard: + soc.add_spi_sdcard() + if args.with_sdcard: + soc.add_sdcard() + builder = Builder(soc, **builder_argdict(args)) + builder.build(run=args.build) + + if args.load: + prog = soc.platform.create_programmer() + prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bit")) + +if __name__ == "__main__": + main() diff --git a/test/test_targets.py b/test/test_targets.py index 1c9dc18..e45a9c4 100644 --- a/test/test_targets.py +++ b/test/test_targets.py @@ -43,6 +43,7 @@ class TestTargets(unittest.TestCase): platforms.append("ac701") platforms.append("aller") platforms.append("arty") + platforms.append("basys3") platforms.append("mimas_a7") platforms.append("netv2") platforms.append("nexys4ddr")