#!/usr/bin/env python3 # This file is Copyright (c) 2019-2020 Florent Kermarrec # License: BSD import argparse from migen import * from litex_boards.platforms import linsn_rv901t from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * from litex.soc.cores.clock import S6PLL from litedram.modules import M12L64322A from litedram.phy import GENSDRPHY from liteeth.phy.s6rgmii import LiteEthPHYRGMII from liteeth.mac import LiteEthMAC # CRG ---------------------------------------------------------------------------------------------- class _CRG(Module): def __init__(self, platform, sys_clk_freq): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True) # # # clk25 = platform.request("clk25") platform.add_period_constraint(clk25, 1e9/25e6) self.submodules.pll = pll = S6PLL(speedgrade=-2) pll.register_clkin(clk25, 25e6) pll.create_clkout(self.cd_sys, sys_clk_freq) pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=270) self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC", i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, i_C0=self.cd_sys.clk, i_C1=~self.cd_sys.clk, o_Q=platform.request("sdram_clock")) # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCSDRAM): def __init__(self, **kwargs): platform = linsn_rv901t.Platform() sys_clk_freq = int(75e6) # SoCSDRAM --------------------------------------------------------------------------------- SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) # SDR SDRAM -------------------------------------------------------------------------------- self.submodules.sdrphy = GENSDRPHY(platform.request("sdram")) sdram_module = M12L64322A(sys_clk_freq, "1:1") self.register_sdram(self.sdrphy, sdram_module.geom_settings, sdram_module.timing_settings) # EthernetSoC -------------------------------------------------------------------------------------- class EthernetSoC(BaseSoC): mem_map = { "ethmac": 0xb0000000, } mem_map.update(BaseSoC.mem_map) def __init__(self, eth_phy=0, **kwargs): BaseSoC.__init__(self, **kwargs) # Ethernet --------------------------------------------------------------------------------- # phy self.submodules.ethphy = LiteEthPHYRGMII( clock_pads = self.platform.request("eth_clocks", eth_phy), pads = self.platform.request("eth", eth_phy)) self.add_csr("ethphy") # mac self.submodules.ethmac = LiteEthMAC( phy = self.ethphy, dw = 32, interface = "wishbone", endianness = self.cpu.endianness) self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus, 0x2000) self.add_csr("ethmac") self.add_interrupt("ethmac") # timing constraints self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 1e9/125e6) self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 1e9/125e6) self.platform.add_false_path_constraints( self.crg.cd_sys.clk, self.ethphy.crg.cd_eth_rx.clk, self.ethphy.crg.cd_eth_tx.clk) # Build -------------------------------------------------------------------------------------------- def main(): parser = argparse.ArgumentParser(description="LiteX SoC on Linsn RV901T") builder_args(parser) soc_sdram_args(parser) parser.add_argument("--with-ethernet", action="store_true", help="enable Ethernet support") parser.add_argument("--eth-phy", default=0, type=int, help="Ethernet PHY 0 or 1 (default=0)") args = parser.parse_args() if args.with_ethernet: soc = EthernetSoC(eth_phy=args.eth_phy, **soc_sdram_argdict(args)) else: soc = BaseSoC(**soc_sdram_argdict(args)) builder = Builder(soc, **builder_argdict(args)) builder.build() if __name__ == "__main__": main()