text: #!/usr/bin/env python3
  
  #
  # This file is part of LiteX-Boards.
  #
  # Copyright (c) 2019 msloniewski <marcin.sloniewski@gmail.com>
  # SPDX-License-Identifier: BSD-2-Clause
  
  import os
  import argparse
  
  from migen import *
  from litex_boards.platforms import deca
  
  from litex.soc.cores.clock import Max10PLL
  from litex.soc.integration.soc_core import *
  from litex.soc.integration.builder import *
  from litex.soc.cores.video import VideoDVIPHY
  from litex.soc.cores.led import LedChaser
  from litex.soc.cores.bitbang import I2CMaster
  
  # CRG ----------------------------------------------------------------------------------------------
  
  class _CRG(Module):
      def __init__(self, platform, sys_clk_freq, with_usb_pll=False):
          self.rst = Signal()
          self.clock_domains.cd_sys    = ClockDomain()
          self.clock_domains.cd_hdmi   = ClockDomain()
          self.clock_domains.cd_usb    = ClockDomain()
  
          # # #
  
          # Clk / Rst.
          clk50 = platform.request("clk50")
  
          # PLL
          self.submodules.pll = pll = Max10PLL(speedgrade="-6")
          self.comb += pll.reset.eq(self.rst)
          pll.register_clkin(clk50, 50e6)
          pll.create_clkout(self.cd_sys,  sys_clk_freq)
          pll.create_clkout(self.cd_hdmi, 40e6)
  
          # USB PLL.
          if with_usb_pll:
              ulpi  = platform.request("ulpi")
              self.comb += ulpi.cs.eq(1) # Enable ULPI chip to enable the ULPI clock.
              self.submodules.usb_pll = pll = Max10PLL(speedgrade="-6")
              self.comb += pll.reset.eq(self.rst)
              pll.register_clkin(ulpi.clk, 60e6)
              pll.create_clkout(self.cd_usb, 60e6, phase=-120) # -120° from DECA's example (also validated with LUNA).
  
  # BaseSoC ------------------------------------------------------------------------------------------
  
  class BaseSoC(SoCCore):
      def __init__(self, sys_clk_freq=int(50e6), with_led_chaser=True, with_video_terminal=False,
                   **kwargs):
          self.platform = platform = deca.Platform()
  
          # Defaults to JTAG-UART since no hardware UART.
          if kwargs["uart_name"] == "serial":
              kwargs["uart_name"] = "jtag_atlantic"
  
          # SoCCore ----------------------------------------------------------------------------------
          SoCCore.__init__(self, platform, sys_clk_freq,
              ident = "LiteX SoC on Terasic DECA",
              **kwargs)
  
          # CRG --------------------------------------------------------------------------------------
          self.submodules.crg = self.crg = _CRG(platform, sys_clk_freq, with_usb_pll=False)
  
          # Video ------------------------------------------------------------------------------------
          if with_video_terminal:
              self.submodules.videophy = VideoDVIPHY(platform.request("hdmi"), clock_domain="hdmi")
              self.add_video_terminal(phy=self.videophy, timings="800x600@60Hz", clock_domain="hdmi")
  
          # Leds -------------------------------------------------------------------------------------
          if with_led_chaser:
              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 DECA")
      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=50e6,        help="System clock frequency.")
      parser.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal (VGA).")
      builder_args(parser)
      soc_core_args(parser)
      args = parser.parse_args()
  
      soc = BaseSoC(
          sys_clk_freq             = int(float(args.sys_clk_freq)),
          with_video_terminal      = args.with_video_terminal,
          **soc_core_argdict(args)
      )
      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 + ".sof"))
  
  if __name__ == "__main__":
      main()
  