text: #!/usr/bin/env python3
  
  #
  # This file is part of LiteX-Boards.
  #
  # Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
  # SPDX-License-Identifier: BSD-2-Clause
  
  import os
  import argparse
  
  from migen import *
  
  from litex_boards.platforms import genesys2
  
  from litex.soc.cores.clock import *
  from litex.soc.integration.soc_core import *
  from litex.soc.integration.soc_sdram import *
  from litex.soc.integration.builder import *
  from litex.soc.cores.led import LedChaser
  
  from litedram.modules import MT41J256M16
  from litedram.phy import s7ddrphy
  
  from liteeth.phy.s7rgmii 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_idelay = ClockDomain()
  
          # # #
  
          self.submodules.pll = pll = S7MMCM(speedgrade=-2)
          self.comb += pll.reset.eq(~platform.request("cpu_reset_n") | self.rst)
          pll.register_clkin(platform.request("clk200"), 200e6)
          pll.create_clkout(self.cd_sys,    sys_clk_freq)
          pll.create_clkout(self.cd_sys4x,  4*sys_clk_freq)
          pll.create_clkout(self.cd_idelay, 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.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
  
  # BaseSoC ------------------------------------------------------------------------------------------
  
  class BaseSoC(SoCCore):
      def __init__(self, sys_clk_freq=int(100e6), with_ethernet=False, with_etherbone=False, **kwargs):
          platform = genesys2.Platform()
  
          # SoCCore ----------------------------------------------------------------------------------
          SoCCore.__init__(self, platform, sys_clk_freq,
              ident          = "LiteX SoC on Genesys2",
              ident_version  = True,
              **kwargs)
  
          # CRG --------------------------------------------------------------------------------------
          self.submodules.crg = _CRG(platform, sys_clk_freq)
  
          # 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)
              self.add_csr("ddrphy")
              self.add_sdram("sdram",
                  phy                     = self.ddrphy,
                  module                  = MT41J256M16(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
              )
  
          # Ethernet / Etherbone ---------------------------------------------------------------------
          if with_ethernet or with_etherbone:
              self.submodules.ethphy = LiteEthPHYRGMII(
                  clock_pads = self.platform.request("eth_clocks"),
                  pads       = self.platform.request("eth"))
              self.add_csr("ethphy")
              if with_ethernet:
                  self.add_ethernet(phy=self.ethphy)
              if with_etherbone:
                  self.add_etherbone(phy=self.ethphy)
  
          # Leds -------------------------------------------------------------------------------------
          self.submodules.leds = LedChaser(
              pads         = platform.request_all("user_led"),
              sys_clk_freq = sys_clk_freq)
          self.add_csr("leds")
  
  # Build --------------------------------------------------------------------------------------------
  
  def main():
      parser = argparse.ArgumentParser(description="LiteX SoC on Genesys2")
      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=100e6,       help="System clock frequency (default: 100MHz)")
      parser.add_argument("--with-ethernet",  action="store_true", help="Enable Ethernet support")
      parser.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support")
      parser.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support")
      parser.add_argument("--with-sdcard",     action="store_true", help="Enable SDCard support")
      builder_args(parser)
      soc_sdram_args(parser)
      args = parser.parse_args()
  
      assert not (args.with_ethernet and args.with_etherbone)
      soc = BaseSoC(
          sys_clk_freq   = int(float(args.sys_clk_freq)),
          with_ethernet  = args.with_ethernet,
          with_etherbone = args.with_etherbone,
          **soc_sdram_argdict(args)
      )
      assert not (args.with_spi_sdcard and args.with_sdcard)
      if args.with_spi_sdcard:
          soc.add_spi_sdcard()
      if args.with_sdcard:
          soc.add_sdcard()
      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()
  