Newer
Older
#!/usr/bin/env python3
# This file is Copyright (c) 2018-2019 Rohit Singh <rohit@rohitksingh.in>
Florent Kermarrec
committed
# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
# License: BSD
Florent Kermarrec
committed
import argparse
import sys
from migen import *
from migen.genlib.misc import WaitTimer
from litex.build import tools
from litex_boards.platforms import aller
from litex.soc.interconnect.csr import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.soc_sdram import *
from litex.soc.integration.builder import *
from litex.soc.integration.export import *
from litex.soc.cores.clock import *
from litex.soc.cores.dna import DNA
from litex.soc.cores.xadc import XADC
from litex.soc.cores.icap import ICAP
from litedram.modules import MT41J128M16
from litedram.phy import s7ddrphy
from litepcie.phy.s7pciephy import S7PCIEPHY
from litepcie.core import LitePCIeEndpoint, LitePCIeMSI
from litepcie.frontend.dma import LitePCIeDMA
from litepcie.frontend.wishbone import LitePCIeWishboneBridge
# CRG ----------------------------------------------------------------------------------------------
def __init__(self, platform, sys_clk_freq):
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_clk200 = ClockDomain()
clk100 = platform.request("clk100")
# Delay software reset by 10us to ensure write has been acked on PCIe.
rst_delay = WaitTimer(int(10e-6*sys_clk_freq))
self.submodules += rst_delay
self.sync += If(self.rst.re, rst_delay.wait.eq(1))
# PLL
self.submodules.pll = pll = S7PLL()
self.comb += pll.reset.eq(rst_delay.done)
pll.register_clkin(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_clk200, 200e6)
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200)
Florent Kermarrec
committed
# PCIeSoC -----------------------------------------------------------------------------------------
class PCIeSoC(SoCCore):
Florent Kermarrec
committed
def __init__(self, platform, **kwargs):
sys_clk_freq = int(100e6)
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on Aller",
ident_version = True,
Florent Kermarrec
committed
**kwargs)
Florent Kermarrec
committed
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = CRG(platform, sys_clk_freq)
self.add_csr("crg")
Florent Kermarrec
committed
# DNA --------------------------------------------------------------------------------------
self.submodules.dna = DNA()
self.dna.add_timing_constraints(platform, sys_clk_freq, self.crg.cd_sys.clk)
self.add_csr("dna")
Florent Kermarrec
committed
# XADC -------------------------------------------------------------------------------------
self.submodules.xadc = XADC()
self.add_csr("xadc")
# ICAP -------------------------------------------------------------------------------------
self.submodules.icap = ICAP(platform)
self.icap.add_timing_constraints(platform, sys_clk_freq, self.crg.cd_sys.clk)
self.add_csr("icap")
# 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,
iodelay_clk_freq = 200e6)
self.add_csr("ddrphy")
self.add_sdram("sdram",
phy = self.ddrphy,
module = MT41J128M16(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
)
Florent Kermarrec
committed
# PCIe -------------------------------------------------------------------------------------
# PHY
self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x1"),
data_width = 64,
bar0_size = 0x20000)
platform.add_false_path_constraints(self.crg.cd_sys.clk, self.pcie_phy.cd_pcie.clk)
self.add_csr("pcie_phy")
self.submodules.pcie_endpoint = LitePCIeEndpoint(self.pcie_phy)
# Wishbone bridge
self.submodules.pcie_bridge = LitePCIeWishboneBridge(self.pcie_endpoint,
base_address = self.mem_map["csr"])
self.add_wb_master(self.pcie_bridge.wishbone)
# DMA0
self.submodules.pcie_dma0 = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint,
with_buffering = True, buffering_depth=1024,
with_loopback = True)
self.add_csr("pcie_dma0")
# DMA1
self.submodules.pcie_dma1 = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint,
with_buffering = True, buffering_depth=1024,
with_loopback = True)
self.add_csr("pcie_dma1")
self.add_constant("DMA_CHANNELS", 2)
# MSI
self.submodules.pcie_msi = LitePCIeMSI()
self.add_csr("pcie_msi")
self.comb += self.pcie_msi.source.connect(self.pcie_phy.msi)
self.interrupts = {
"PCIE_DMA0_WRITER": self.pcie_dma0.writer.irq,
"PCIE_DMA0_READER": self.pcie_dma0.reader.irq,
"PCIE_DMA1_WRITER": self.pcie_dma1.writer.irq,
"PCIE_DMA1_READER": self.pcie_dma1.reader.irq,
for i, (k, v) in enumerate(sorted(self.interrupts.items())):
self.comb += self.pcie_msi.irqs[i].eq(v)
self.add_constant(k + "_INTERRUPT", i)
def generate_software_headers(self):
csr_header = get_csr_header(self.csr_regions, self.constants, with_access_functions=False)
tools.write_to_file("csr.h", csr_header)
soc_header = get_soc_header(self.constants, with_access_functions=False)
tools.write_to_file("soc.h", soc_header)
mem_header = get_mem_header(self.mem_regions)
tools.write_to_file("mem.h", mem_header)
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on Aller")
Florent Kermarrec
committed
builder_args(parser)
soc_sdram_args(parser)
args = parser.parse_args()
# Enforce arguments
args.uart_name = "crossover"
Florent Kermarrec
committed
args.csr_data_width = 32
platform = aller.Platform()
soc = PCIeSoC(platform, **soc_sdram_argdict(args))
builder = Builder(soc, **builder_argdict(args))
vns = builder.build()
soc.generate_software_headers()
if __name__ == "__main__":
main()