From 1c87c391c42ef56ac916fa285a6e6bc3dd2f716b Mon Sep 17 00:00:00 2001 From: Derek Mulcahy Date: Tue, 14 Dec 2021 16:00:42 -0500 Subject: [PATCH] Initial release for Snickerdoodle --- litex_boards/platforms/snickerdoodle.py | 73 +++++++++++++ litex_boards/targets/snickerdoodle.py | 133 ++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 litex_boards/platforms/snickerdoodle.py create mode 100755 litex_boards/targets/snickerdoodle.py diff --git a/litex_boards/platforms/snickerdoodle.py b/litex_boards/platforms/snickerdoodle.py new file mode 100644 index 0000000..99bd6e6 --- /dev/null +++ b/litex_boards/platforms/snickerdoodle.py @@ -0,0 +1,73 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2019-2020 Florent Kermarrec +# Copyright (c) 2021 Derek Mulcahy , +# SPDX-License-Identifier: BSD-2-Clause + +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform, VivadoProgrammer + + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ +] + +_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)), + ), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + ("ja1", "- - - G14 E18 D20 E19 D19 - - F16 B20 F17 C20 - - E17 A20 D18 B19 - - F19 G20 F20 G19 - - J20 G18 H20 G17 - - J18 H17 H18 H16 - -"), + ("ja2", "- - - J15 L14 J16 L15 K16 - - M14 G15 M15 H15 - - N15 J14 N16 K14 - - L19 J19 L20 K19 - - M17 M20 M18 M19 - - L16 K18 L17 K17 - -"), + ("jb1", "- - - T19 T11 U12 T10 T12 - - P14 W13 R14 V12 - - U13 T14 V13 T14 - - T16 Y17 U17 Y16 - - W14 W15 Y14 V15 - - U14 U19 U15 U18 - -"), + ("jb2", "- - - R19 N17 P16 P18 P15 - - T17 R17 R18 R16 - - V17 W19 V18 W18 - - T20 W16 U20 V16 - - V20 Y19 W20 Y18 - - N20 P19 P20 N18 - -"), + ("jc1", "- - - V5 U7 U10 V7 T9 - - T5 Y13 U5 Y12 - - V11 W6 V10 V6 - - V8 Y11 W8 W11 - - U9 W9 U8 W10 - - Y9 Y6 Y8 Y7 - -"), + # ("xadc", "N15 L14 K16 K14 N16 L15 J16 J14"), + # ("mrcc", "H17 H16 K18 K17 U19 U18 P19 N18 Y6 Y7"), + # ("srcc", "J18 H18 L16 L17 U14 U15 N20 P20 Y9 Y8"), +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(XilinxPlatform): + # The clock speed depends on the PS7 PLL configuration for the FCLK_CLK0 signal. + default_clk_name = "clk100" + default_clk_period = 1e9/100e6 + + def __init__(self): + XilinxPlatform.__init__(self, "xc7z010-clg400-1", _io, _connectors, toolchain="vivado") + self.add_extension(_ps7_io) + + def create_programmer(self): + return VivadoProgrammer(flash_part="n25q128a") + + 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/snickerdoodle.py b/litex_boards/targets/snickerdoodle.py new file mode 100755 index 0000000..dc86632 --- /dev/null +++ b/litex_boards/targets/snickerdoodle.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2019-2020 Florent Kermarrec , +# Copyright (c) 2021 Derek Mulcahy , +# SPDX-License-Identifier: BSD-2-Clause + +import os +import argparse + +from migen import * + +from litex_boards.platforms import snickerdoodle +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 * + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq, use_ps7_clk=True): + self.rst = Signal() + self.clock_domains.cd_sys = ClockDomain() + + # # # + + if use_ps7_clk: + assert sys_clk_freq == 100e6 + self.comb += ClockSignal("sys").eq(ClockSignal("ps7")) + self.comb += ResetSignal("sys").eq(ResetSignal("ps7") | self.rst) + else: + raise NotImplementedError + +# BaseSoC ------------------------------------------------------------------------------------------ + +def load_ps7(soc, xci_file): + odir = os.path.join("build", "snickerdoodle", "gateware", "xci") + os.makedirs(odir, exist_ok=True) + file = "snickerdoodle_ps7.xci" + dst = os.path.join(odir, file) + if xci_file is None: + src = "https://technicaltoys-support.s3.amazonaws.com/xci/" + file + os.system("wget " + src + " -O " + dst) + else: + os.system("cp -p " + xci_file + " " + dst) + soc.cpu.set_ps7_xci(dst) + +def blinky(soc, platform): + from litex.build.generic_platform import Pins, IOStandard + platform.add_extension([("blinky_led", 0, Pins("ja1:3"), IOStandard("LVCMOS33"))]) + led = platform.request("blinky_led") + soc.submodules.blinky = blinky = Module() + counter = Signal(27) + blinky.comb += led.eq(counter[counter.nbits-1]) + blinky.sync += counter.eq(counter + 1) + +class BaseSoC(SoCCore): + + def __init__(self, sys_clk_freq=int(100e6), + with_blinky = False, + blinky_led = "ja1:3", + xci_file = None, + **kwargs): + + platform = snickerdoodle.Platform() + + kwargs["with_uart"] = False + kwargs["cpu_type"] = "zynq7000" + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "Snickerdoodle", + ident_version = True, + **kwargs) + + # Zynq7000 Integration --------------------------------------------------------------------- + if kwargs.get("cpu_type", None) == "zynq7000": + load_ps7(self, xci_file) + + # 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) + + platform.add_platform_command("set_property BITSTREAM.GENERAL.COMPRESS True [current_design]") + + if with_blinky: + blinky(self, platform) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on Snickerdoodle") + parser.add_argument("--build", action="store_true", help="Build bitstream") + parser.add_argument("--load", action="store_true", help="Load bitstream") + parser.add_argument("--with-blinky", action="store_true", help="Enable Blinky") + parser.add_argument("--blinky-led", default="ja1:3", help="Blinky LED") + parser.add_argument("--xci-file", help="XCI for PS7 configuration") + parser.add_argument("--target", help="Programmer target") + builder_args(parser) + soc_core_args(parser) + vivado_build_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + with_blinky = args.with_blinky, + blinky_led = args.blinky_led, + xci_file = args.xci_file, + **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() + bitstream = os.path.join(builder.gateware_dir, soc.build_name + ".bit") + prog.load_bitstream(bitstream, target=args.target, device=1) + +if __name__ == "__main__": + main()