mirror of
https://github.com/litex-hub/litex-boards.git
synced 2025-01-03 03:43:36 -05:00
ba01776432
- main_ram mem_map is now directly used by add_sdram when origin is None. - max_sdram_size/min_l2_data_width are no longer exposed as targets arguments this can still be used enforced directly in the few cases it is useful.
185 lines
8.1 KiB
Python
Executable file
185 lines
8.1 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
#
|
|
# This file is part of LiteX-Boards.
|
|
#
|
|
# Copyright (c) 2018-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
|
# SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
import os
|
|
import argparse
|
|
|
|
from migen import *
|
|
from migen.genlib.resetsync import AsyncResetSynchronizer
|
|
|
|
from litex_boards.platforms import kcu105
|
|
|
|
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
|
|
|
|
# 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("clk125"), 125e6)
|
|
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_pcie=False, with_sata=False, **kwargs):
|
|
platform = kcu105.Platform()
|
|
|
|
# SoCCore ----------------------------------------------------------------------------------
|
|
SoCCore.__init__(self, platform, sys_clk_freq,
|
|
ident = "LiteX SoC on KCU105",
|
|
ident_version = True,
|
|
**kwargs)
|
|
|
|
# CRG --------------------------------------------------------------------------------------
|
|
self.submodules.crg = _CRG(platform, sys_clk_freq)
|
|
|
|
# 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)
|
|
)
|
|
|
|
# Ethernet / Etherbone ---------------------------------------------------------------------
|
|
if with_ethernet or with_etherbone:
|
|
self.submodules.ethphy = KU_1000BASEX(self.crg.cd_eth.clk,
|
|
data_pads = self.platform.request("sfp", 0),
|
|
sys_clk_freq = self.clk_freq)
|
|
self.comb += self.platform.request("sfp_tx_disable_n", 0).eq(1)
|
|
self.platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks REQP-1753]")
|
|
if with_ethernet:
|
|
self.add_ethernet(phy=self.ethphy)
|
|
if with_etherbone:
|
|
self.add_etherbone(phy=self.ethphy, ip_address=eth_ip)
|
|
|
|
# PCIe -------------------------------------------------------------------------------------
|
|
if with_pcie:
|
|
self.submodules.pcie_phy = USPCIEPHY(platform, platform.request("pcie_x4"),
|
|
data_width = 128,
|
|
bar0_size = 0x20000)
|
|
self.add_pcie(phy=self.pcie_phy, ndmas=1)
|
|
|
|
# SATA -------------------------------------------------------------------------------------
|
|
if with_sata:
|
|
from litex.build.generic_platform import Subsignal, Pins
|
|
from litesata.phy import LiteSATAPHY
|
|
|
|
# IOs
|
|
_sata_io = [
|
|
# SFP 2 SATA Adapter / https://shop.trenz-electronic.de/en/TE0424-01-SFP-2-SATA-Adapter
|
|
("sfp2sata", 0,
|
|
Subsignal("tx_p", Pins("U4")),
|
|
Subsignal("tx_n", Pins("U3")),
|
|
Subsignal("rx_p", Pins("T2")),
|
|
Subsignal("rx_n", Pins("T1")),
|
|
),
|
|
]
|
|
platform.add_extension(_sata_io)
|
|
|
|
# RefClk, Generate 150MHz from PLL.
|
|
self.clock_domains.cd_sata_refclk = ClockDomain()
|
|
self.crg.pll.create_clkout(self.cd_sata_refclk, 150e6)
|
|
sata_refclk = ClockSignal("sata_refclk")
|
|
platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks REQP-1753]")
|
|
|
|
# PHY
|
|
self.submodules.sata_phy = LiteSATAPHY(platform.device,
|
|
refclk = sata_refclk,
|
|
pads = platform.request("sfp2sata"),
|
|
gen = "gen2",
|
|
clk_freq = sys_clk_freq,
|
|
data_width = 16)
|
|
|
|
# Core
|
|
self.add_sata(phy=self.sata_phy, mode="read+write")
|
|
|
|
# Leds -------------------------------------------------------------------------------------
|
|
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 KCU105")
|
|
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)")
|
|
ethopts = parser.add_mutually_exclusive_group()
|
|
ethopts.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
|
|
ethopts.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support")
|
|
parser.add_argument("--eth-ip", default="192.168.1.50", type=str, help="Ethernet/Etherbone IP address")
|
|
parser.add_argument("--with-pcie", action="store_true", help="Enable PCIe support")
|
|
parser.add_argument("--driver", action="store_true", help="Generate PCIe driver")
|
|
parser.add_argument("--with-sata", action="store_true", help="Enable SATA support (over SFP2SATA)")
|
|
builder_args(parser)
|
|
soc_core_args(parser)
|
|
args = parser.parse_args()
|
|
|
|
soc = BaseSoC(
|
|
sys_clk_freq = int(float(args.sys_clk_freq)),
|
|
with_ethernet = args.with_ethernet,
|
|
with_etherbone = args.with_etherbone,
|
|
eth_ip = args.eth_ip,
|
|
with_pcie = args.with_pcie,
|
|
with_sata = args.with_sata,
|
|
**soc_core_argdict(args)
|
|
)
|
|
builder = Builder(soc, **builder_argdict(args))
|
|
builder.build(run=args.build)
|
|
|
|
if args.driver:
|
|
generate_litepcie_software(soc, os.path.join(builder.output_dir, "driver"))
|
|
|
|
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()
|