#!/usr/bin/env python3 # This file is Copyright (c) 2018-2019 Rohit Singh # This file is Copyright (c) 2019 Florent Kermarrec # License: BSD import argparse import sys from migen import * from litex.build import tools from litex_boards.platforms import nereid 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 MT8KTF51264 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 ---------------------------------------------------------------------------------------------- class CRG(Module, AutoCSR): def __init__(self, platform, sys_clk_freq): self.reset = CSR() # FIXME: not used for now self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) self.clock_domains.cd_clk200 = ClockDomain() clk100 = platform.request("clk100") platform.add_period_constraint(clk100, 1e9/100e6) self.submodules.pll = pll = S7PLL() self.comb += pll.reset.eq(platform.request("cpu_reset")) 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_clk200, 200e6) self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200) # PCIeSoC ----------------------------------------------------------------------------------------- class PCIeSoC(SoCCore): def __init__(self, platform, **kwargs): sys_clk_freq = int(100e6) # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, ident = "LiteX SoC on Nereid", ident_version = True, **kwargs) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = CRG(platform, sys_clk_freq) self.add_csr("crg") # DNA -------------------------------------------------------------------------------------- self.submodules.dna = DNA() self.dna.add_timing_constraints(platform, sys_clk_freq, self.crg.cd_sys.clk) self.add_csr("dna") # 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.K7DDRPHY(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 = MT8KTF51264(sys_clk_freq, "1:4", speedgrade="800"), 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 ) # 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") # Endpoint 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 Tagus") builder_args(parser) soc_sdram_args(parser) args = parser.parse_args() # Enforce arguments args.uart_name = "crossover" args.csr_data_width = 32 platform = nereid.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()