Merge pull request #271 from antmicro/add-data-center-board

WIP: boards: added datacenter DDR4 RDIMM tester board
This commit is contained in:
enjoy-digital 2021-10-18 13:36:37 +02:00 committed by GitHub
commit a53f17380f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 316 additions and 0 deletions

View File

@ -0,0 +1,144 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2021 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform
from litex.build.openocd import OpenOCD
# IOs ----------------------------------------------------------------------------------------------
_io = [
# TODO: change clock when assigned to schematic
("clk100", 0, Pins("AC23"), IOStandard("LVCMOS33")),
("user_led", 0, Pins("D21"), IOStandard("LVCMOS33")),
("user_led", 1, Pins("B20"), IOStandard("LVCMOS33")),
("user_led", 2, Pins("B21"), IOStandard("LVCMOS33")),
("user_led", 3, Pins("C22"), IOStandard("LVCMOS33")),
("user_led", 4, Pins("E22"), IOStandard("LVCMOS33")),
("user_btn", 0, Pins("C21"), IOStandard("LVCMOS33")),
("user_btn", 1, Pins("A20"), IOStandard("LVCMOS33")),
("user_btn", 2, Pins("E21"), IOStandard("LVCMOS33")),
("user_btn", 3, Pins("D23"), IOStandard("LVCMOS33")),
("serial", 0,
Subsignal("tx", Pins("E26")),
Subsignal("rx", Pins("F25")),
IOStandard("LVCMOS33")
),
("serial", 1,
Subsignal("tx", Pins("D26")),
Subsignal("rx", Pins("E25")),
IOStandard("LVCMOS33")
),
# DDR4
("ddr4", 0,
Subsignal("a", Pins(
"AF10 AC11 AD11 AD10 AC9 AD9 AB9 AF7 AE8",
"AE7 Y12 AC7 AB7 AD13"),
IOStandard("SSTL12_DCI")),
Subsignal("ba", Pins("AB11 AB10"), IOStandard("SSTL12_DCI")),
Subsignal("bg", Pins("AA9 AF9"), IOStandard("SSTL12_DCI")),
Subsignal("ras_n", Pins("AA12"), IOStandard("SSTL12_DCI")), # A16
Subsignal("cas_n", Pins("AF13"), IOStandard("SSTL12_DCI")), # A15
Subsignal("we_n", Pins("AA13"), IOStandard("SSTL12_DCI")), # A14
Subsignal("cs_n", Pins("W13 AA14 AC14 AF15"), IOStandard("SSTL12_DCI")),
Subsignal("act_n", Pins("Y8"), IOStandard("SSTL12_DCI")),
Subsignal("alert_n", Pins("AE10"), IOStandard("SSTL12_DCI")),
Subsignal("par", Pins("AE13"), IOStandard("SSTL12_DCI")),
Subsignal("dm", Pins("AF3 AE5 AD6 AC6 AF2 AE3 AE6 AD5"),
IOStandard("SSTL12_DCI")),
Subsignal("dq", Pins(
"W11 Y11 V7 Y7 V11 V9 V8 W8",
"U2 V6 Y2 Y3 U5 U4 W3 Y1",
"AA2 AB2 AE1 AE2 V2 W1 AD1 AC2",
"W4 AA3 AD3 AC4 V3 V4 AB4 AC3",
"AC16 AC17 AB16 AA19 AB15 AD16 AC18 AC19",
"AF17 AE17 AF20 AD19 AE15 AE16 AF19 AD18",
"Y18 Y17 W14 V14 AA20 AA15 V18 W16",
"AA18 AB19 V16 W15 AB17 AA17 V19 V17"),
IOStandard("SSTL12")),
Subsignal("dqs_p", Pins(
"W10 W6 AB1 AA5 AD20 AE18 W18 Y15 AF5",
"B17 D19 L19 J15 T24 P19 R16 M25 AC8"),
IOStandard("DIFF_HSUL_12")),
Subsignal("dqs_n", Pins(
"W9 W5 AC1 AB5 AE20 AF18 W19 Y16 AF4",
"A17 D20 L20 J16 T25 P20 R17 L25 AD8"),
IOStandard("DIFF_HSUL_12")),
Subsignal("clk_p", Pins("AE12 AB12"), IOStandard("DIFF_SSTL12_DCI")),
Subsignal("clk_n", Pins("AF12 AC12"), IOStandard("DIFF_SSTL12_DCI")),
Subsignal("cke", Pins("AA8 AA7"), IOStandard("SSTL12_DCI")), # also AM15 for larger SODIMMs
Subsignal("odt", Pins("Y13 AB14"), IOStandard("SSTL12_DCI")), # also AM16 for larger SODIMMs
Subsignal("reset_n", Pins("AB6"), IOStandard("SSTL12")),
Misc("SLEW=FAST"),
),
# RGMII Ethernet
("eth_ref_clk", 0, Pins("AA23"), IOStandard("LVCMOS33")),
("eth_clocks", 0,
Subsignal("tx", Pins("Y23")),
Subsignal("rx", Pins("AA24")),
IOStandard("LVCMOS33")
),
("eth", 0,
Subsignal("rst_n", Pins("AA22")),
Subsignal("mdio", Pins("AB26")),
Subsignal("mdc", Pins("AA25")),
Subsignal("rx_ctl", Pins("Y25")),
Subsignal("rx_data", Pins("W26 W25 V26 U25")),
Subsignal("tx_ctl", Pins("U26")),
Subsignal("tx_data", Pins("W24 Y26 Y22 Y21")),
IOStandard("LVCMOS33")
),
# HyperRAM
("hyperram", 0,
Subsignal("clk_n", Pins("AE26")),
Subsignal("clk_p", Pins("AD26")),
Subsignal("rst_n", Pins("AC24")),
Subsignal("cs_n", Pins("AC26")),
Subsignal("dq", Pins("AE23 AD25 AF24 AE22 AF23 AF25 AE25 AD24")),
Subsignal("rwds", Pins("AD23")),
IOStandard("LVCMOS33")
),
# SD Card
("sdcard", 0,
Subsignal("data", Pins("E10 F8 C9 D9"), Misc("PULLUP True")),
Subsignal("cmd", Pins("D8"), Misc("PULLUP True")),
Subsignal("clk", Pins("D10")),
Subsignal("cd", Pins("F9")),
Misc("SLEW=FAST"),
IOStandard("LVCMOS33"),
),
]
# Platform -----------------------------------------------------------------------------------------
class Platform(XilinxPlatform):
default_clk_name = "clk100"
default_clk_period = 1e9/100e6
def __init__(self, device="xc7k160tffg676-1"):
XilinxPlatform.__init__(self, device, _io, 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.6 [get_iobanks 32]")
self.add_platform_command("set_property INTERNAL_VREF 0.6 [get_iobanks 33]")
self.add_platform_command("set_property INTERNAL_VREF 0.6 [get_iobanks 34]")
def create_programmer(self):
return OpenOCD("openocd_xc7_ft4232.cfg", "bscan_spi_xc7k100t.bit")
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>
# SPDX-License-Identifier: BSD-2-Clause
import os
import argparse
from migen import *
from litex_boards.platforms import datacenter_ddr4_test_board
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 MTA18ASF2G72PZ
from litedram.phy.s7ddrphy import K7DDRPHY
from liteeth.phy import LiteEthS7PHYRGMII
from litehyperbus.core.hyperbus import HyperRAM
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq, iodelay_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_idelay = ClockDomain()
# # #
self.submodules.pll = pll = S7PLL(speedgrade=-1)
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_idelay, iodelay_clk_freq)
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
mem_map = {
"hyperram": 0x20000000,
}
mem_map.update(SoCCore.mem_map)
def __init__(self, *, sys_clk_freq=int(100e6), iodelay_clk_freq=200e6,
with_ethernet=False, with_etherbone=False, eth_ip="192.168.1.50", eth_dynamic_ip=False,
with_hyperram=False, with_sdcard=False, with_jtagbone=True, with_uartbone=False,
with_led_chaser=True, ident_version=True, **kwargs):
platform = datacenter_ddr4_test_board.Platform()
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on data center test board",
ident_version = ident_version,
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq, iodelay_clk_freq=iodelay_clk_freq)
# DDR4 SDRAM RDIMM -------------------------------------------------------------------------
if not self.integrated_main_ram_size:
self.submodules.ddrphy = K7DDRPHY(platform.request("ddr4"),
memtype = "DDR4",
iodelay_clk_freq = iodelay_clk_freq,
sys_clk_freq = sys_clk_freq,
is_rdimm = True,
)
self.add_sdram("sdram",
phy = self.ddrphy,
module = MTA18ASF2G72PZ(sys_clk_freq, "1:4"),
l2_cache_size = kwargs.get("l2_size", 8192),
l2_cache_min_data_width = 256,
size = 0x40000000,
)
# HyperRAM ---------------------------------------------------------------------------------
if with_hyperram:
self.submodules.hyperram = HyperRAM(platform.request("hyperram"))
self.register_mem("hyperram", self.mem_map["hyperram"], self.hyperram.bus, 8*1024*1024)
# SD Card ----------------------------------------------------------------------------------
if with_sdcard:
self.add_sdcard()
# Ethernet / Etherbone ---------------------------------------------------------------------
if with_ethernet or with_etherbone:
# Traces between PHY and FPGA introduce ignorable delays of ~0.165ns +/- 0.015ns.
# PHY chip does not introduce delays on TX (FPGA->PHY), however it includes 1.2ns
# delay for RX CLK so we only need 0.8ns to match the desired 2ns.
self.submodules.ethphy = LiteEthS7PHYRGMII(
clock_pads = self.platform.request("eth_clocks"),
pads = self.platform.request("eth"),
rx_delay = 0.8e-9,
)
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)
# UartBone ---------------------------------------------------------------------------------
if with_uartbone:
self.add_uartbone("serial", baudrate=1e6)
# Leds -------------------------------------------------------------------------------------
if with_led_chaser:
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 LPDDR4 Test Board")
target = parser.add_argument_group(title="Target options")
target.add_argument("--build", action="store_true", help="Build bitstream")
target.add_argument("--load", action="store_true", help="Load bitstream")
target.add_argument("--flash", action="store_true", help="Flash bitstream")
target.add_argument("--sys-clk-freq", default=50e6, help="System clock frequency")
target.add_argument("--iodelay-clk-freq", default=200e6, help="IODELAYCTRL frequency")
ethopts = target.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.add_argument("--eth-ip", default="192.168.1.50", help="Ethernet/Etherbone IP address")
target.add_argument("--eth-dynamic-ip", action="store_true", help="Enable dynamic Ethernet IP addresses setting")
target.add_argument("--with-hyperram", action="store_true", help="Add HyperRAM")
target.add_argument("--with-sdcard", action="store_true", help="Add SDCard")
target.add_argument("--with-jtagbone", action="store_true", help="Add JTAGBone")
target.add_argument("--with-uartbone", action="store_true", help="Add UartBone on 2nd serial")
parser.add_argument("--no-ident-version", action="store_false", help="Disable build time output")
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(
sys_clk_freq = int(float(args.sys_clk_freq)),
iodelay_clk_freq = int(float(args.iodelay_clk_freq)),
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
eth_ip = args.eth_ip,
eth_dynamic_ip = args.eth_dynamic_ip,
with_hyperram = args.with_hyperram,
with_sdcard = args.with_sdcard,
with_jtagbone = args.with_jtagbone,
with_uartbone = args.with_uartbone,
ident_version = args.no_ident_version,
**soc_core_argdict(args))
builder = Builder(soc, **builder_argdict(args))
vns = 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"))
if args.flash:
prog = soc.platform.create_programmer()
prog.flash(0, os.path.join(builder.gateware_dir, soc.build_name + ".bin"))
if __name__ == "__main__":
main()