From bbb1ded9f80693cabba932f4096b5b8219d0a652 Mon Sep 17 00:00:00 2001 From: Staf Verhaegen Date: Sun, 12 Apr 2020 21:20:22 +0200 Subject: [PATCH] Added Arty S7 board As the pin-out is totally different from the A7 board I did put this in a separate class and not as a variant of the Arty board. Used migen Arty S7 board file and Digilent xdc file as reference. --- litex_boards/platforms/artys7.py | 211 +++++++++++++++++++++++++++++++ litex_boards/targets/artys7.py | 91 +++++++++++++ 2 files changed, 302 insertions(+) create mode 100644 litex_boards/platforms/artys7.py create mode 100755 litex_boards/targets/artys7.py diff --git a/litex_boards/platforms/artys7.py b/litex_boards/platforms/artys7.py new file mode 100644 index 0000000..ecf7b22 --- /dev/null +++ b/litex_boards/platforms/artys7.py @@ -0,0 +1,211 @@ +# This file is Copyright (c) 2015 Yann Sionneau +# This file is Copyright (c) 2015-2019 Florent Kermarrec +# License: BSD + +from litex.build.generic_platform import Pins, Subsignal, IOStandard, Misc +from litex.build.xilinx import XilinxPlatform, VivadoProgrammer + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + ("user_led", 0, Pins("E18"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("F13"), IOStandard("LVCMOS33")), + ("user_led", 2, Pins("E13"), IOStandard("LVCMOS33")), + ("user_led", 3, Pins("H15"), IOStandard("LVCMOS33")), + + ("rgb_led", 0, + Subsignal("r", Pins("J15")), + Subsignal("g", Pins("G17")), + Subsignal("b", Pins("F15")), + IOStandard("LVCMOS33") + ), + + ("rgb_led", 1, + Subsignal("r", Pins("E15")), + Subsignal("g", Pins("F18")), + Subsignal("b", Pins("E14")), + IOStandard("LVCMOS33") + ), + + ("user_sw", 0, Pins("H14"), IOStandard("LVCMOS33")), + ("user_sw", 1, Pins("H18"), IOStandard("LVCMOS33")), + ("user_sw", 2, Pins("G18"), IOStandard("LVCMOS33")), + ("user_sw", 3, Pins("M5"), IOStandard("SSTL135")), + + ("user_btn", 0, Pins("G15"), IOStandard("LVCMOS33")), + ("user_btn", 1, Pins("K16"), IOStandard("LVCMOS33")), + ("user_btn", 2, Pins("J16"), IOStandard("LVCMOS33")), + ("user_btn", 3, Pins("H13"), IOStandard("LVCMOS33")), + + ("clk100", 0, Pins("R2"), IOStandard("SSTL135")), + + ("cpu_reset", 0, Pins("C18"), IOStandard("LVCMOS33")), + + ("serial", 0, + Subsignal("tx", Pins("R12")), + Subsignal("rx", Pins("V12")), + IOStandard("LVCMOS33")), + + ("spi", 0, + Subsignal("clk", Pins("G16")), + Subsignal("cs_n", Pins("H16")), + Subsignal("mosi", Pins("H17")), + Subsignal("miso", Pins("K14")), + IOStandard("LVCMOS33") + ), + + ("i2c", 0, + Subsignal("scl", Pins("J14")), + Subsignal("sda", Pins("J13")), + IOStandard("LVCMOS33"), + ), + + ("spiflash4x", 0, # clock needs to be accessed through STARTUPE2 + Subsignal("cs_n", Pins("M13")), + Subsignal("clk", Pins("D11")), + Subsignal("dq", Pins("K17", "K18", "L14", "M15")), + IOStandard("LVCMOS33") + ), + ("spiflash", 0, # clock needs to be accessed through STARTUPE2 + Subsignal("cs_n", Pins("M13")), + Subsignal("clk", Pins("D11")), + Subsignal("mosi", Pins("K17")), + Subsignal("miso", Pins("K18")), + Subsignal("wp", Pins("L14")), + Subsignal("hold", Pins("M15")), + IOStandard("LVCMOS33") + ), + + ("ddram", 0, + Subsignal("a", Pins( + "U2 R4 V2 V4 T3 R7 V6 T6", + "U7 V7 P6 T5 R6 U6"), + IOStandard("SSTL135")), + Subsignal("ba", Pins("V5 T1 U3"), IOStandard("SSTL135")), + Subsignal("ras_n", Pins("U1"), IOStandard("SSTL135")), + Subsignal("cas_n", Pins("V3"), IOStandard("SSTL135")), + Subsignal("we_n", Pins("P7"), IOStandard("SSTL135")), + Subsignal("cs_n", Pins("R3"), IOStandard("SSTL135")), + Subsignal("dm", Pins("K4 M3"), IOStandard("SSTL135")), + Subsignal("dq", Pins( + "K2 K3 L4 M6 K6 M4 L5 L6", + "N4 R1 N1 N5 M2 P1 M1 P2"), + IOStandard("SSTL135"), + Misc("IN_TERM=UNTUNED_SPLIT_40")), + Subsignal("dqs_p", Pins("K1 N3"), + IOStandard("DIFF_SSTL135"), + Misc("IN_TERM=UNTUNED_SPLIT_40")), + Subsignal("dqs_n", Pins("L1 N2"), + IOStandard("DIFF_SSTL135"), + Misc("IN_TERM=UNTUNED_SPLIT_40")), + Subsignal("clk_p", Pins("R5"), IOStandard("DIFF_SSTL135")), + Subsignal("clk_n", Pins("T4"), IOStandard("DIFF_SSTL135")), + Subsignal("cke", Pins("T2"), IOStandard("SSTL135")), + Subsignal("odt", Pins("P5"), IOStandard("SSTL135")), + Subsignal("reset_n", Pins("J6"), IOStandard("SSTL135")), + Misc("SLEW=FAST"), + ), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + ("pmoda", "L17 L18 M14 N14 M16 M17 M18 N18"), + ("pmodb", "P17 P18 R18 T18 P14 P15 N15 P16"), + ("pmodc", "U15 V16 U17 U18 U16 P13 R13 V14"), + ("pmodd", "V15 U12 V13 T12 T13 R11 T11 U11"), + ("ck_io", { + # Outer Digital Header + "ck_io0" : "L13", + "ck_io1" : "N13", + "ck_io2" : "L16", + "ck_io3" : "R14", + "ck_io4" : "T14", + "ck_io5" : "R16", + "ck_io6" : "R17", + "ck_io7" : "V17", + "ck_io8" : "R15", + "ck_io9" : "T15", + "ck_io10" : "H16", + "ck_io11" : "H17", + "ck_io12" : "K14", + "ck_io13" : "G16", + + # Inner Digital Header + "ck_io26" : "U11", + "ck_io27" : "T11", + "ck_io28" : "R11", + "ck_io29" : "T13", + "ck_io30" : "T12", + "ck_io31" : "V13", + "ck_io32" : "U12", + "ck_io33" : "V15", + "ck_io34" : "V14", + "ck_io35" : "R13", + "ck_io36" : "P13", + "ck_io37" : "U16", + "ck_io38" : "U18", + "ck_io39" : "U17", + "ck_io40" : "V16", + "ck_io41" : "U15", + + # Outer Analog Header as Digital IO + "ck_a0" : "G13", + "ck_a1" : "B16", + "ck_a2" : "A16", + "ck_a3" : "C13", + "ck_a4" : "C14", + "ck_a5" : "D18", + + # Inner Analog Header as Digital IO + "ck_a6" : "B14", + "ck_a7" : "A14", + "ck_a8" : "D16", + "ck_a9" : "D17", + "ck_a10" : "D14", + "ck_a11" : "D15", + } ), + ("XADC", { + # Outer Analog Header + "vaux0_p" : "B13", + "vaux0_n" : "A13", + "vaux1_p" : "B15", + "vaux1_n" : "A15", + "vaux9_p" : "E12", + "vaux9_n" : "D12", + "vaux2_p" : "B17", + "vaux2_n" : "A17", + "vaux10_p" : "C17", + "vaux10_n" : "B18", + "vaux11_p" : "E16", + "vaux11_n" : "E17", + + # Inner Analog Header + "vaux8_p" : "B14", + "vaux8_n" : "A14", + "vaux3_p" : "D16", + "vaux3_n" : "D17", + } ), +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(XilinxPlatform): + default_clk_name = "clk100" + default_clk_period = 1e9/100e6 + + def __init__(self, variant="s7-50"): + device = { + "s7-25": "xc7s25csga324-1", + "s7-50": "xc7s50csga324-1" + }[variant] + XilinxPlatform.__init__(self, device, _io, _connectors, toolchain="vivado") + self.toolchain.bitstream_commands = \ + ["set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]"] + self.toolchain.additional_commands = \ + ["write_cfgmem -force -format bin -interface spix4 -size 16 " + "-loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"] + self.add_platform_command("set_property INTERNAL_VREF 0.675 [get_iobanks 34]") + + def create_programmer(self): + return VivadoProgrammer(flash_part="n25q128-3.3v-spi-x1_x2_x4") diff --git a/litex_boards/targets/artys7.py b/litex_boards/targets/artys7.py new file mode 100755 index 0000000..00a09a5 --- /dev/null +++ b/litex_boards/targets/artys7.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 + +# This file is Copyright (c) 2015-2019 Florent Kermarrec , +# Copyright (c) 2020 Staf Verhaegen +# License: BSD + +import argparse + +from migen import Module, ClockDomain + +from ..platforms import artys7 +from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict + +from litex.soc.cores.clock import S7PLL, S7IDELAYCTRL +from litex.soc.integration.soc_core import SoCCore +from litex.soc.integration.soc_sdram import soc_sdram_args, soc_sdram_argdict +from litex.soc.integration.builder import Builder, builder_args, builder_argdict + +from litedram.modules import MT41K128M16 +from litedram.phy import s7ddrphy + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys2x = ClockDomain(reset_less=True) + self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) + self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) + self.clock_domains.cd_clk200 = ClockDomain() + + # # # + + self.submodules.pll = pll = S7PLL(speedgrade=-1) + self.comb += pll.reset.eq(~platform.request("cpu_reset")) + pll.register_clkin(platform.request("clk100"), 100e6) + pll.create_clkout(self.cd_sys, sys_clk_freq) + pll.create_clkout(self.cd_sys2x, 2*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_clk200, 200e6) + + self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=int(100e6), **kwargs): + platform = artys7.Platform() + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # DDR3 SDRAM ------------------------------------------------------------------------------- + if not self.integrated_main_ram_size: + self.submodules.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"), + memtype = "DDR3", + nphases = 4, + sys_clk_freq = sys_clk_freq, + interface_type = "MEMORY") + self.add_csr("ddrphy") + self.add_sdram("sdram", + phy = self.ddrphy, + module = MT41K128M16(sys_clk_freq, "1:4"), + origin = self.mem_map["main_ram"], + size = kwargs.get("max_sdram_size", 0x40000000), + l2_cache_size = kwargs.get("l2_size", 8192), + l2_cache_min_data_width = kwargs.get("min_l2_data_width", 128), + l2_cache_reverse = True + ) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on Arty") + builder_args(parser) + soc_sdram_args(parser) + vivado_build_args(parser) + args = parser.parse_args() + + soc = BaseSoC(with_ethernet=False, with_etherbone=False, + **soc_sdram_argdict(args)) + builder = Builder(soc, **builder_argdict(args)) + builder.build(**vivado_build_argdict(args)) + + +if __name__ == "__main__": + main()