3 # This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
4 # This file is Copyright (c) 2018 David Shah <dave@ds0.me>
12 from migen
.genlib
.resetsync
import AsyncResetSynchronizer
14 from litex
.build
.io
import DDROutput
16 from litex
.boards
.platforms
import ulx3s
18 from litex
.build
.lattice
.trellis
import trellis_args
, trellis_argdict
20 from litex
.soc
.cores
.clock
import *
21 from litex
.soc
.integration
.soc_core
import *
22 from litex
.soc
.integration
.soc_sdram
import *
23 from litex
.soc
.integration
.builder
import *
25 from litedram
import modules
as litedram_modules
26 from litedram
.phy
import GENSDRPHY
28 # CRG ----------------------------------------------------------------------------------------------
31 def __init__(self
, platform
, sys_clk_freq
, with_usb_pll
=False):
32 self
.clock_domains
.cd_sys
= ClockDomain()
33 self
.clock_domains
.cd_sys_ps
= ClockDomain(reset_less
=True)
38 clk25
= platform
.request("clk25")
39 rst
= platform
.request("rst")
42 self
.submodules
.pll
= pll
= ECP5PLL()
43 self
.comb
+= pll
.reset
.eq(rst
)
44 pll
.register_clkin(clk25
, 25e6
)
45 pll
.create_clkout(self
.cd_sys
, sys_clk_freq
)
46 pll
.create_clkout(self
.cd_sys_ps
, sys_clk_freq
, phase
=90)
47 self
.specials
+= AsyncResetSynchronizer(self
.cd_sys
, ~pll
.locked | rst
)
51 self
.submodules
.usb_pll
= usb_pll
= ECP5PLL()
52 usb_pll
.register_clkin(clk25
, 25e6
)
53 self
.clock_domains
.cd_usb_12
= ClockDomain()
54 self
.clock_domains
.cd_usb_48
= ClockDomain()
55 usb_pll
.create_clkout(self
.cd_usb_12
, 12e6
, margin
=0)
56 usb_pll
.create_clkout(self
.cd_usb_48
, 48e6
, margin
=0)
59 self
.specials
+= DDROutput(1, 0, platform
.request("sdram_clock"), ClockSignal("sys_ps"))
61 # Prevent ESP32 from resetting FPGA
62 self
.comb
+= platform
.request("wifi_gpio0").eq(1)
64 # BaseSoC ------------------------------------------------------------------------------------------
66 class BaseSoC(SoCCore
):
67 def __init__(self
, device
="LFE5U-45F", toolchain
="trellis",
68 sys_clk_freq
=int(50e6
), sdram_module_cls
="MT48LC16M16", **kwargs
):
70 platform
= ulx3s
.Platform(device
=device
, toolchain
=toolchain
)
72 # SoCCore ----------------------------------------------------------------------------------
73 SoCCore
.__init
__(self
, platform
, clk_freq
=sys_clk_freq
, **kwargs
)
75 # CRG --------------------------------------------------------------------------------------
76 with_usb_pll
= kwargs
.get("uart_name", None) == "usb_acm"
77 self
.submodules
.crg
= _CRG(platform
, sys_clk_freq
, with_usb_pll
)
79 # SDR SDRAM --------------------------------------------------------------------------------
80 if not self
.integrated_main_ram_size
:
81 self
.submodules
.sdrphy
= GENSDRPHY(platform
.request("sdram"))
82 self
.add_sdram("sdram",
84 module
= getattr(litedram_modules
, sdram_module_cls
)(sys_clk_freq
, "1:1"),
85 origin
= self
.mem_map
["main_ram"],
86 size
= kwargs
.get("max_sdram_size", 0x40000000),
87 l2_cache_size
= kwargs
.get("l2_size", 8192),
88 l2_cache_min_data_width
= kwargs
.get("min_l2_data_width", 128),
89 l2_cache_reverse
= True
92 # Build --------------------------------------------------------------------------------------------
95 parser
= argparse
.ArgumentParser(description
="LiteX SoC on ULX3S")
96 parser
.add_argument("--build", action
="store_true", help="Build bitstream")
97 parser
.add_argument("--load", action
="store_true", help="Load bitstream")
98 parser
.add_argument("--gateware-toolchain", dest
="toolchain", default
="trellis", help="Gateware toolchain to use, trellis (default) or diamond")
99 parser
.add_argument("--device", dest
="device", default
="LFE5U-45F", help="FPGA device, ULX3S can be populated with LFE5U-45F (default) or LFE5U-85F")
100 parser
.add_argument("--sys-clk-freq", default
=50e6
, help="System clock frequency (default=50MHz)")
101 parser
.add_argument("--sdram-module", default
="MT48LC16M16", help="SDRAM module: MT48LC16M16, AS4C32M16 or AS4C16M16 (default=MT48LC16M16)")
103 soc_sdram_args(parser
)
105 args
= parser
.parse_args()
107 soc
= BaseSoC(device
=args
.device
, toolchain
=args
.toolchain
,
108 sys_clk_freq
=int(float(args
.sys_clk_freq
)),
109 sdram_module_cls
=args
.sdram_module
,
110 **soc_sdram_argdict(args
))
111 builder
= Builder(soc
, **builder_argdict(args
))
112 builder_kargs
= trellis_argdict(args
) if args
.toolchain
== "trellis" else {}
113 builder
.build(**builder_kargs
, run
=args
.build
)
116 prog
= soc
.platform
.create_programmer()
117 prog
.load_bitstream(os
.path
.join(builder
.gateware_dir
, "top.svf"))
119 if __name__
== "__main__":