Merge pull request #416 from shenki/artix-dc-scm

Add Antmicro Artix DC-SCM board
This commit is contained in:
enjoy-digital 2022-08-24 15:22:52 +02:00 committed by GitHub
commit feff243f8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 312 additions and 0 deletions

View File

@ -0,0 +1,140 @@
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform
from litex.build.openocd import OpenOCD
# IOs ----------------------------------------------------------------------------------------------
_io = [
# Clk / Rst
("clk100", 0, Pins("C18"), IOStandard("LVCMOS33")),
# Leds
("user_led", 0, Pins("T20"), IOStandard("LVCMOS33")),
("user_led", 1, Pins("U20"), IOStandard("LVCMOS33")),
("user_led", 2, Pins("W20"), IOStandard("LVCMOS33")),
# Serial
("serial", 0,
Subsignal("tx", Pins("R19")),
Subsignal("rx", Pins("P19")),
IOStandard("LVCMOS33"),
),
("serial", 1,
Subsignal("tx", Pins("U21")),
Subsignal("rx", Pins("T21")),
IOStandard("LVCMOS33"),
),
# DDR3 SDRAM (voltage changed from 1.5V to 1.35V)
("ddram", 0,
Subsignal("a", Pins(
"M2 M5 M3 M1 L6 P1 N3 N2",
"M6 R1 L5 N5 N4 P2 P6"),
IOStandard("SSTL135")),
Subsignal("ba", Pins("L3 K6 L4"), IOStandard("SSTL135")),
Subsignal("ras_n", Pins("J4"), IOStandard("SSTL135")),
Subsignal("cas_n", Pins("K3"), IOStandard("SSTL135")),
Subsignal("we_n", Pins("L1"), IOStandard("SSTL135")),
Subsignal("dm", Pins("G3 F1"), IOStandard("SSTL135")),
Subsignal("dq", Pins(
"G2 H4 H5 J1 K1 H3 H2 J5",
"E3 B2 F3 D2 C2 A1 E2 B1"),
IOStandard("SSTL135"),
Misc("IN_TERM=UNTUNED_SPLIT_40")),
Subsignal("dqs_p", Pins("K2 E1"),
IOStandard("DIFF_SSTL135"),
Misc("IN_TERM=UNTUNED_SPLIT_40")),
Subsignal("dqs_n", Pins("J2 D1"),
IOStandard("DIFF_SSTL135"),
Misc("IN_TERM=UNTUNED_SPLIT_40")),
Subsignal("clk_p", Pins("P5"), IOStandard("DIFF_SSTL135")),
Subsignal("clk_n", Pins("P4"), IOStandard("DIFF_SSTL135")),
Subsignal("cke", Pins("J6"), IOStandard("SSTL135")),
Subsignal("odt", Pins("K4"), IOStandard("SSTL135")),
Subsignal("reset_n", Pins("G1"), IOStandard("SSTL135")),
Misc("SLEW=FAST"),
),
# eMMC - there are pullups on the board so we don't enable them here
("sdcard", 0,
Subsignal("data", Pins("P17 W17 R18 V18")),
Subsignal("cmd", Pins("Y19")),
Subsignal("clk", Pins("Y18")),
#Subsignal("cd", Pins(),
Misc("SLEW=FAST"),
IOStandard("LVCMOS33"),
),
# RGMII Ethernet
("eth_ref_clk", 0, Pins("H19"), IOStandard("LVCMOS33")), # 125 MHz if enabled?
("eth_clocks", 0,
Subsignal("tx", Pins("J19")),
Subsignal("rx", Pins("K19")),
IOStandard("LVCMOS33")
),
("eth", 0,
Subsignal("rst_n", Pins("N18"), IOStandard("LVCMOS33")),
Subsignal("int_n", Pins("N20"), IOStandard("LVCMOS33")),
Subsignal("mdio", Pins("M21"), IOStandard("LVCMOS33")),
Subsignal("mdc", Pins("N22"), IOStandard("LVCMOS33")),
Subsignal("rx_ctl", Pins("M22"), IOStandard("LVCMOS33")),
Subsignal("rx_data", Pins("L20 L21 K21 K22"), IOStandard("LVCMOS33")),
Subsignal("tx_ctl", Pins("J22"), IOStandard("LVCMOS33")),
Subsignal("tx_data", Pins("G20 H20 H22 J21"), IOStandard("LVCMOS33")),
),
# PCIe
("pcie_x1", 0,
# Subsignal("rst_n", Pins(""), IOStandard("LVCMOS33")),
Subsignal("clk_p", Pins("F6")),
Subsignal("clk_n", Pins("E6")),
Subsignal("rx_p", Pins("B8")),
Subsignal("rx_n", Pins("A8")),
Subsignal("tx_p", Pins("B4")),
Subsignal("tx_n", Pins("A4"))
),
# USB ULPI
("ulpi_clock", 0, Pins("W19"), IOStandard("LVCMOS33")),
("ulpi", 0,
Subsignal("data", Pins("AB18 AA18 AA19 AB20 AA20 AB21 AA21 AB22")),
Subsignal("dir", Pins("W21")),
Subsignal("stp", Pins("Y22")),
Subsignal("nxt", Pins("W22")),
Subsignal("rst", Pins("V20")),
IOStandard("LVCMOS33"), Misc("SLEW=FAST")
),
("ulpi_clock", 1, Pins("V4"), IOStandard("LVCMOS33")),
("ulpi", 1,
Subsignal("data", Pins("AB2 AA3 AB3 Y4 AA4 AB5 AA5 AB6")),
Subsignal("dir", Pins("AB7")),
Subsignal("stp", Pins("AA6")),
Subsignal("nxt", Pins("AB8")),
Subsignal("rst", Pins("AA8")),
IOStandard("LVCMOS33"), Misc("SLEW=FAST")
),
]
# Platform -----------------------------------------------------------------------------------------
class Platform(XilinxPlatform):
default_clk_name = "clk100"
default_clk_period = 1e9/100e6
def __init__(self, device="xc7a100tfgg484-1", toolchain="vivado"):
XilinxPlatform.__init__(self, device, _io, toolchain=toolchain)
# 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 35]")
def create_programmer(self):
bscan_spi = "bscan_spi_xc7a100t.bit" if "xc7a100t" in self.device else "bscan_spi_xc7a35t.bit"
return OpenOCD("openocd_xc7_ft2232.cfg", bscan_spi)
def do_finalize(self, fragment):
XilinxPlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("clk100", loose=True), 1e9/100e6)

View File

@ -0,0 +1,172 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2021 Antmicro <www.antmicro.com>
# Copyright (c) 2022 IBM Corp.
# SPDX-License-Identifier: BSD-2-Clause
import os
import math
from migen import *
from litex_boards.platforms import antmicro_artix_dc_scm
from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict
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
from litedram.modules import MT41K128M16
from litedram.phy import s7ddrphy
from liteeth.phy import LiteEthS7PHYRGMII
from litepcie.phy.s7pciephy import S7PCIEPHY
# 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_ulpi0 = ClockDomain()
self.clock_domains.cd_ulpi1 = ClockDomain()
# ulpi0 clock domain (60MHz from ulpi0)
self.comb += self.cd_ulpi0.clk.eq(platform.request("ulpi_clock", 0))
# ulpi1 clock domain (60MHz from ulpi1)
self.comb += self.cd_ulpi1.clk.eq(platform.request("ulpi_clock", 1))
# # #
self.submodules.pll = pll = S7PLL(speedgrade=-1)
# self.comb += pll.reset.eq(~platform.request("cpu_reset") | self.rst)
self.comb += pll.reset.eq(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)
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, *, device, with_pcie, with_etherbone, with_ethernet, with_sdram, eth_dynamic_ip,
eth_reset_time, toolchain="vivado", sys_clk_freq=int(100e6), eth_ip="192.168.1.120", **kwargs):
platform = antmicro_artix_dc_scm.Platform(device=device, toolchain=toolchain)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq, ident = "LiteX SoC on Artix DC-SCM", **kwargs)
# 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)
self.add_sdram("sdram",
phy = self.ddrphy,
module = MT41K128M16(sys_clk_freq, "1:4"),
l2_cache_size = kwargs.get("l2_size", 8192)
)
# Ethernet / Etherbone ---------------------------------------------------------------------
if with_ethernet or with_etherbone:
self.submodules.ethphy = LiteEthS7PHYRGMII(
clock_pads = self.platform.request("eth_clocks"),
pads = self.platform.request("eth"),
hw_reset_cycles = math.ceil(float(eth_reset_time) * self.sys_clk_freq)
)
if with_ethernet:
self.add_ethernet(phy=self.ethphy, dynamic_ip=eth_dynamic_ip)
if with_etherbone:
self.add_etherbone(phy=self.ethphy, ip_address=eth_ip)
platform.add_platform_command("set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets main_ethphy_eth_rx_clk_ibuf]")
# PCIe -------------------------------------------------------------------------------------
if with_pcie:
self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x1"),
data_width = 128,
bar0_size = 0x20000)
self.add_csr("pcie_phy")
self.add_pcie(phy=self.pcie_phy, ndmas=1)
# Leds -------------------------------------------------------------------------------------
self.submodules.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)
self.add_csr("leds")
# Build --------------------------------------------------------------------------------------------
def main():
from litex.soc.integration.soc import LiteXSoCArgumentParser
parser = LiteXSoCArgumentParser(description="LiteX SoC on Artix DC-SCM")
target_group = parser.add_argument_group(title="Target options")
target_group.add_argument("--toolchain", default="vivado", help="FPGA toolchain (vivado or symbiflow).")
target_group.add_argument("--build", action="store_true", help="Build design.")
target_group.add_argument("--load", action="store_true", help="Load bitstream.")
target_group.add_argument("--flash", action="store_true", help="Flash bitstream")
target_group.add_argument("--sys-clk-freq", default=100e6, help="System clock frequency.")
target_group.add_argument("--device", default="xc7a100tfgg484-1", choices=["xc7a100tfgg484-1", "xc7a15tfgg484-1"])
target_group.add_argument("--with-pcie", action="store_true", help="Add PCIe")
ethopts = target_group.add_mutually_exclusive_group()
ethopts.add_argument("--with-ethernet", action="store_true", help="Add Ethernet")
ethopts.add_argument("--with-etherbone", action="store_true", help="Add EtherBone")
target_group.add_argument("--eth-ip", default="192.168.1.50", help="Ethernet/Etherbone IP address")
target_group.add_argument("--eth-dynamic-ip", action="store_true", help="Enable dynamic Ethernet IP addresses setting")
target_group.add_argument("--eth-reset-time", default="10e-3", help="Duration of Ethernet PHY reset")
target_group.add_argument("--with-sdram", action="store_true", help="Add SDRAM")
target_group.add_argument("--with-emmc", action="store_true", help="Add eMMC")
builder_args(parser)
soc_core_args(parser)
vivado_build_args(parser)
args = parser.parse_args()
assert not (args.with_etherbone and args.eth_dynamic_ip)
soc = BaseSoC(
toolchain = args.toolchain,
device = args.device,
sys_clk_freq = int(float(args.sys_clk_freq)),
with_pcie = args.with_pcie,
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
eth_ip = args.eth_ip,
eth_dynamic_ip = args.eth_dynamic_ip,
with_sdram = args.with_sdram,
eth_reset_time = args.eth_reset_time,
**soc_core_argdict(args)
)
if args.with_emmc:
soc.add_sdcard(software_debug=False)
builder = Builder(soc, **builder_argdict(args))
builder_kwargs = vivado_build_argdict(args) if args.toolchain == "vivado" else {}
if args.build:
builder.build(**builder_kwargs)
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
if args.flash:
prog = soc.platform.create_programmer()
prog.flash(0, builder.get_bitstream_filename(mode="flash"))
if __name__ == "__main__":
main()