Merge pull request #395 from AEW2015/master

Support for "discontinued" Avnet aes-ku040-db-g development board
This commit is contained in:
enjoy-digital 2022-06-07 12:13:47 +02:00 committed by GitHub
commit d37af4aece
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 335 additions and 0 deletions

View File

@ -105,6 +105,7 @@ Some of the suported boards, see yours? Give LiteX-Boards a try!
├── antmicro_lpddr4_test_board ├── antmicro_lpddr4_test_board
├── arduino_mkrvidor4000 ├── arduino_mkrvidor4000
├── avalanche ├── avalanche
├── avnet_aesku40
├── berkeleylab_marblemini ├── berkeleylab_marblemini
├── berkeleylab_marble ├── berkeleylab_marble
├── camlink_4k ├── camlink_4k

View File

@ -0,0 +1,199 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2022 Andrew Elbert Wilson <andrew.e.wilson@ieee.org>
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
# IOs ----------------------------------------------------------------------------------------------
_io = [
# Clk / Rst
("clk250", 0,
Subsignal("p", Pins("H22"), IOStandard("LVDS")),
Subsignal("n", Pins("H23"), IOStandard("LVDS"))
),
("cpu_reset", 0, Pins("N24"), IOStandard("LVCMOS12")),
# Serial
("serial", 0,
Subsignal("tx", Pins("D20")),
Subsignal("rx", Pins("C19")),
IOStandard("LVCMOS18")
),
# MII Ethernet
("eth_clocks", 0,
Subsignal("tx", Pins("G10")),
Subsignal("rx", Pins("E11")),
IOStandard("LVCMOS18")
),
("eth", 0,
Subsignal("rst_n", Pins("D9")),
#Subsignal("int_n", Pins("Y14")),
Subsignal("mdio", Pins("C8")),
Subsignal("mdc", Pins("C9")),
Subsignal("rx_ctl", Pins("D11")),
Subsignal("rx_data", Pins("A10 B10 B11 C11")),
Subsignal("tx_ctl", Pins("G9")),
Subsignal("tx_data", Pins("H8 H9 J9 J10")),
IOStandard("LVCMOS18")
),
# DDR4 SDRAM
("ddram", 0,
Subsignal("a", Pins(
"AA24 AB24 AB26 AC26 AA22 AB22 Y23 AA23",
"AC23 AC24 W23 W24 W25 W26"),
IOStandard("SSTL12_DCI")),
Subsignal("ba", Pins("V26 U24"), IOStandard("SSTL12_DCI")),
Subsignal("bg", Pins("V24"), IOStandard("SSTL12_DCI")),
Subsignal("ras_n", Pins("U26"), IOStandard("SSTL12_DCI")), # A16
Subsignal("cas_n", Pins("Y26"), IOStandard("SSTL12_DCI")), # A15
Subsignal("we_n", Pins("Y25"), IOStandard("SSTL12_DCI")), # A14
Subsignal("cs_n", Pins("V22"), IOStandard("SSTL12_DCI")),
Subsignal("act_n", Pins("T24"), IOStandard("SSTL12_DCI")),
#Subsignal("ten", Pins("AH16"), IOStandard("SSTL12_DCI")),
#Subsignal("alert_n", Pins("AJ16"), IOStandard("SSTL12_DCI")),
#Subsignal("par", Pins("AD18"), IOStandard("SSTL12_DCI")),
Subsignal("dm", Pins("T23 R18 N23 E25"),
IOStandard("POD12_DCI")),
Subsignal("dq", Pins(
"T22 U22 P26 R26 P23 P24 P25 R25",
"P21 R21 P18 P19 P20 R20 U20 U21",
"N26 M26 M24 L24 N22 M22 M25 L25",
"H26 G26 G25 F25 J24 J25 H24 G24"),
IOStandard("POD12_DCI"),
Misc("PRE_EMPHASIS=RDRV_240"),
Misc("EQUALIZATION=EQ_LEVEL2")),
Subsignal("dqs_p", Pins("R22 T19 K26 F22"),
IOStandard("DIFF_POD12_DCI"),
Misc("PRE_EMPHASIS=RDRV_240"),
Misc("EQUALIZATION=EQ_LEVEL2")),
Subsignal("dqs_n", Pins("R23 T20 J26 F23"),
IOStandard("DIFF_POD12_DCI"),
Misc("PRE_EMPHASIS=RDRV_240"),
Misc("EQUALIZATION=EQ_LEVEL2")),
Subsignal("clk_p", Pins("AA25"), IOStandard("DIFF_SSTL12_DCI")),
Subsignal("clk_n", Pins("AB25"), IOStandard("DIFF_SSTL12_DCI")),
Subsignal("cke", Pins("V23"), IOStandard("SSTL12_DCI")),
Subsignal("odt", Pins("U25"), IOStandard("SSTL12_DCI")),
Subsignal("reset_n", Pins("T25"), IOStandard("LVCMOS12")),
Misc("SLEW=FAST"),
),
]
# Connectors ---------------------------------------------------------------------------------------
_connectors = [
("pmod0", "J13 H13 A13 A12 C12 B12 D13 C13"),
("pmod1", "F9 F8 E8 D8 E10 D10 G12 F12"),
]
# PMODS --------------------------------------------------------------------------------------------
def raw_pmod_io(pmod):
return [(pmod, 0, Pins(" ".join([f"{pmod}:{i:d}" for i in range(8)])), IOStandard("LVCMOS33"))]
def usb_pmod_io(pmod):
return [
# USB-UART PMOD: https://store.digilentinc.com/pmod-usbuart-usb-to-uart-interface/
("usb_uart", 0,
Subsignal("tx", Pins(f"{pmod}:1")),
Subsignal("rx", Pins(f"{pmod}:2")),
IOStandard("LVCMOS18")
),
]
_usb_uart_pmod_io = usb_pmod_io("pmod0") # USB-UART PMOD on JB.
def i2s_pmod_io(pmod):
return [
# I2S PMOD: https://store.digilentinc.com/pmod-i2s2-stereo-audio-input-and-output/
("i2s_rx_mclk", 0, Pins(f"{pmod}:4"), IOStandard("LVCMOS33")),
("i2s_rx", 0,
Subsignal("clk", Pins(f"{pmod}:6")),
Subsignal("sync", Pins(f"{pmod}:5")),
Subsignal("rx", Pins(f"{pmod}:7")),
IOStandard("LVCMOS18"),
),
("i2s_tx_mclk", 0, Pins(f"{pmod}:0"), IOStandard("LVCMOS33")),
("i2s_tx", 0,
Subsignal("clk",Pins(f"{pmod}:2")),
Subsignal("sync", Pins(f"{pmod}:1")),
Subsignal("tx", Pins(f"{pmod}:3")),
IOStandard("LVCMOS18"),
),
]
_i2s_pmod_io = i2s_pmod_io("pmod0") # I2S PMOD on JA.
def sdcard_pmod_io(pmod):
return [
# SDCard PMOD:
# - https://store.digilentinc.com/pmod-microsd-microsd-card-slot/
# - https://github.com/antmicro/arty-expansion-board
("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("LVCMOS18"),
),
("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("LVCMOS18"),
),
]
_sdcard_pmod_io = sdcard_pmod_io("pmod0") # SDCARD PMOD on JD.
def numato_sdcard_pmod_io(pmod):
return [
# SDCard PMOD:
# https://numato.com/product/micro-sd-expansion-module/
# This adaptor does not have the card detect (CD) pin connected
("spisdcard", 0,
Subsignal("clk", Pins(f"{pmod}:5")),
Subsignal("mosi", Pins(f"{pmod}:1"), Misc("PULLUP True")),
Subsignal("cs_n", Pins(f"{pmod}:4"), Misc("PULLUP True")),
Subsignal("miso", Pins(f"{pmod}:2"), Misc("PULLUP True")),
Misc("SLEW=FAST"),
IOStandard("LVCMOS18"),
),
("sdcard", 0,
Subsignal("data", Pins(f"{pmod}:2 {pmod}:6 {pmod}:0 {pmod}:4"), Misc("PULLUP True")),
Subsignal("cmd", Pins(f"{pmod}:1"), Misc("PULLUP True")),
Subsignal("clk", Pins(f"{pmod}:5")),
Misc("SLEW=FAST"),
IOStandard("LVCMOS18"),
),
]
_numato_sdcard_pmod_io = numato_sdcard_pmod_io("pmod0") # SDCARD PMOD on JD.
# Platform -----------------------------------------------------------------------------------------
class Platform(XilinxPlatform):
default_clk_name = "clk250"
default_clk_period = 1e9/250e6
def __init__(self):
XilinxPlatform.__init__(self, "xcku040-fbva676-1-c", _io, _connectors, toolchain="vivado")
def create_programmer(self):
return VivadoProgrammer()
def do_finalize(self, fragment):
XilinxPlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("clk250", loose=True), 1e9/250e6)
self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 44]")
self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 45]")

View File

@ -0,0 +1,135 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2022 Andrew Elbert Wilson <andrew.e.wilson@ieee.org>
# SPDX-License-Identifier: BSD-2-Clause
import os
import argparse
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex_boards.platforms import avnet_aesku40
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 EDY4016A
from litedram.phy import usddrphy
from liteeth.phy.ku_1000basex import KU_1000BASEX
from litepcie.phy.uspciephy import USPCIEPHY
from litepcie.software import generate_litepcie_software
from liteeth.phy.usrgmii import LiteEthPHYRGMII
# 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_pll4x = ClockDomain(reset_less=True)
self.clock_domains.cd_idelay = ClockDomain()
self.clock_domains.cd_eth = ClockDomain()
# # #
self.submodules.pll = pll = USMMCM(speedgrade=-2)
self.comb += pll.reset.eq(platform.request("cpu_reset") | self.rst)
pll.register_clkin(platform.request("clk250"), 250e6)
pll.create_clkout(self.cd_pll4x, sys_clk_freq*4, buf=None, with_reset=False)
pll.create_clkout(self.cd_idelay, 200e6)
pll.create_clkout(self.cd_eth, 200e6)
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst.
self.specials += [
Instance("BUFGCE_DIV", name="main_bufgce_div",
p_BUFGCE_DIVIDE=4,
i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys.clk),
Instance("BUFGCE", name="main_bufgce",
i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys4x.clk),
]
self.submodules.idelayctrl = USIDELAYCTRL(cd_ref=self.cd_idelay, cd_sys=self.cd_sys)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, sys_clk_freq=int(125e6), with_ethernet=False, with_etherbone=False,
eth_ip="192.168.1.50", with_led_chaser=True, with_pcie=False, with_sata=False,
**kwargs):
platform = avnet_aesku40.Platform()
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on AESKU40",
ident_version = True,
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
# Ethernet ---------------------------------------------------------------------------------
if with_ethernet:
self.submodules.ethphy = LiteEthPHYRGMII(
clock_pads = self.platform.request("eth_clocks"),
pads = self.platform.request("eth"),
tx_delay=1e-9, #Supported Delay with 200 MHz ref clk
rx_delay=1e-9)
#Change ref clk for idelay3s
for special in self.ethphy.rx._fragment.specials:
if special.name_override == "IDELAYE3":
for item in special.items:
if item.name == "REFCLK_FREQUENCY":
item.value=200.00
self.add_ethernet(phy=self.ethphy)
# DDR4 SDRAM -------------------------------------------------------------------------------
if not self.integrated_main_ram_size:
self.submodules.ddrphy = usddrphy.USDDRPHY(platform.request("ddram"),
memtype = "DDR4",
sys_clk_freq = sys_clk_freq,
iodelay_clk_freq = 200e6)
self.add_sdram("sdram",
phy = self.ddrphy,
module = EDY4016A(sys_clk_freq, "1:4"),
size = 0x40000000,
l2_cache_size = kwargs.get("l2_size", 8192)
)
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on AESKU40")
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=125e6, help="System clock frequency (default: 125MHz)")
builder_args(parser)
soc_core_args(parser)
args = parser.parse_args()
soc = BaseSoC(
sys_clk_freq = int(float(args.sys_clk_freq)),
**soc_core_argdict(args)
)
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()