Skip to content
Snippets Groups Projects
trellisboard.py 7.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • David Shah's avatar
    David Shah committed
    #!/usr/bin/env python3
    
    
    #
    # This file is part of LiteX-Boards.
    #
    # Copyright (c) 2019 David Shah <dave@ds0.me>
    # SPDX-License-Identifier: BSD-2-Clause
    
    David Shah's avatar
    David Shah committed
    import argparse
    
    from migen import *
    from migen.genlib.resetsync import AsyncResetSynchronizer
    
    
    from litex_boards.platforms import trellisboard
    
    from litex.build.lattice.trellis import trellis_args, trellis_argdict
    
    
    David Shah's avatar
    David Shah committed
    from litex.soc.cores.clock import *
    
    from litex.soc.integration.soc_core import *
    
    David Shah's avatar
    David Shah committed
    from litex.soc.integration.soc_sdram import *
    from litex.soc.integration.builder import *
    
    from litex.soc.cores.led import LedChaser
    
    David Shah's avatar
    David Shah committed
    
    from litedram.modules import MT41J256M16
    from litedram.phy import ECP5DDRPHY
    
    from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
    
    # CRG ----------------------------------------------------------------------------------------------
    
    class _CRG(Module):
    
        def __init__(self, platform, sys_clk_freq):
            self.clock_domains.cd_por     = ClockDomain(reset_less=True)
            self.clock_domains.cd_sys     = ClockDomain()
    
            # # #
    
            # Clk / Rst
            clk12 = platform.request("clk12")
            rst   = platform.request("user_btn", 0)
    
            # Power on reset
            por_count = Signal(16, reset=2**16-1)
            por_done  = Signal()
            self.comb += self.cd_por.clk.eq(clk12)
            self.comb += por_done.eq(por_count == 0)
            self.sync.por += If(~por_done, por_count.eq(por_count - 1))
    
            # PLL
            self.submodules.pll = pll = ECP5PLL()
    
            pll.register_clkin(clk12, 12e6)
            pll.create_clkout(self.cd_sys, sys_clk_freq)
    
    class _CRGSDRAM(Module):
    
    David Shah's avatar
    David Shah committed
        def __init__(self, platform, sys_clk_freq):
    
            self.clock_domains.cd_init    = ClockDomain()
            self.clock_domains.cd_por     = ClockDomain(reset_less=True)
            self.clock_domains.cd_sys     = ClockDomain()
            self.clock_domains.cd_sys2x   = ClockDomain()
    
    David Shah's avatar
    David Shah committed
            self.clock_domains.cd_sys2x_i = ClockDomain(reset_less=True)
    
            # # #
    
    
            self.stop  = Signal()
            self.reset = Signal()
    
            # Clk / Rst
    
    David Shah's avatar
    David Shah committed
            clk12 = platform.request("clk12")
    
            rst   = platform.request("user_btn", 0)
    
            # Power on reset
    
    David Shah's avatar
    David Shah committed
            por_count = Signal(16, reset=2**16-1)
    
            self.comb += self.cd_por.clk.eq(clk12)
    
    David Shah's avatar
    David Shah committed
            self.comb += por_done.eq(por_count == 0)
            self.sync.por += If(~por_done, por_count.eq(por_count - 1))
    
    
    David Shah's avatar
    David Shah committed
            self.submodules.pll = pll = ECP5PLL()
    
    David Shah's avatar
    David Shah committed
            pll.register_clkin(clk12, 12e6)
            pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq)
    
            pll.create_clkout(self.cd_init,   25e6)
    
    David Shah's avatar
    David Shah committed
            self.specials += [
    
                    i_CLK0   = self.cd_sys2x_i.clk,
                    i_SEL    = 0,
                    o_ECSOUT = sys2x_clk_ecsout,
    
    David Shah's avatar
    David Shah committed
                Instance("ECLKSYNCB",
    
                    i_ECLKI = sys2x_clk_ecsout,
                    i_STOP  = self.stop,
                    o_ECLKO = self.cd_sys2x.clk),
    
    David Shah's avatar
    David Shah committed
                Instance("CLKDIVF",
    
                    p_DIV     = "2.0",
                    i_ALIGNWD = 0,
                    i_CLKI    = self.cd_sys2x.clk,
    
                AsyncResetSynchronizer(self.cd_sys,    ~pll.locked | self.reset),
                AsyncResetSynchronizer(self.cd_sys2x,  ~pll.locked | self.reset),
    
            self.comb += platform.request("dram_vtt_en").eq(1)
    
    David Shah's avatar
    David Shah committed
    
    # BaseSoC ------------------------------------------------------------------------------------------
    
    
    class BaseSoC(SoCCore):
        def __init__(self, sys_clk_freq=int(75e6), toolchain="trellis", with_ethernet=False, **kwargs):
    
    David Shah's avatar
    David Shah committed
            platform = trellisboard.Platform(toolchain=toolchain)
    
            # SoCCore ----------------------------------------------------------------------------------
            SoCCore.__init__(self, platform, sys_clk_freq,
                ident          = "LiteX SoC on Trellis Board",
                ident_version  = True,
                **kwargs)
    
            # CRG --------------------------------------------------------------------------------------
    
            crg_cls = _CRGSDRAM if not self.integrated_main_ram_size else _CRG
            self.submodules.crg = crg_cls(platform, sys_clk_freq)
    
            # DDR3 SDRAM -------------------------------------------------------------------------------
    
            if not self.integrated_main_ram_size:
                self.submodules.ddrphy = ECP5DDRPHY(
                    platform.request("ddram"),
                    sys_clk_freq=sys_clk_freq)
    
                self.comb += self.crg.stop.eq(self.ddrphy.init.stop)
                self.comb += self.crg.reset.eq(self.ddrphy.init.reset)
    
                self.add_csr("ddrphy")
                self.add_sdram("sdram",
                    phy                     = self.ddrphy,
                    module                  = MT41J256M16(sys_clk_freq, "1:2"),
                    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 ---------------------------------------------------------------------------------
    
            if with_ethernet:
                self.submodules.ethphy = LiteEthPHYRGMII(
                    clock_pads = self.platform.request("eth_clocks"),
                    pads       = self.platform.request("eth"))
                self.add_csr("ethphy")
                self.add_ethernet(phy=self.ethphy)
    
            # Leds -------------------------------------------------------------------------------------
            self.submodules.leds = LedChaser(
    
                pads         = platform.request_all("user_led"),
    
                sys_clk_freq = sys_clk_freq)
            self.add_csr("leds")
    
    
    David Shah's avatar
    David Shah committed
    # Build --------------------------------------------------------------------------------------------
    
    def main():
    
        parser = argparse.ArgumentParser(description="LiteX SoC on Trellis Board")
    
        parser.add_argument("--build", action="store_true", help="Build bitstream")
        parser.add_argument("--load",  action="store_true", help="Load bitstream")
    
        parser.add_argument("--toolchain", default="trellis", help="Gateware toolchain to use, trellis (default) or diamond")
    
    David Shah's avatar
    David Shah committed
        builder_args(parser)
        soc_sdram_args(parser)
    
        parser.add_argument("--sys-clk-freq",    default=75e6,        help="system clock frequency (default=75MHz)")
        parser.add_argument("--with-ethernet",   action="store_true", help="enable Ethernet 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")
    
    David Shah's avatar
    David Shah committed
        args = parser.parse_args()
    
    
        soc = BaseSoC(sys_clk_freq=int(float(args.sys_clk_freq)),
            with_ethernet=args.with_ethernet,
            **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()
    
    David Shah's avatar
    David Shah committed
        builder = Builder(soc, **builder_argdict(args))
    
        builder_kargs = trellis_argdict(args) if args.toolchain == "trellis" else {}
    
        builder.build(**builder_kargs, run=args.build)
    
        if args.load:
            prog = soc.platform.create_programmer()
    
            prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".svf"))
    
    David Shah's avatar
    David Shah committed
    
    if __name__ == "__main__":
        main()