From b1a6da84b34c720f86faf3a9f9c63a44c62f1910 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Sun, 4 Aug 2024 12:14:56 +0200 Subject: [PATCH] sipeed_tang_primer_25k: add SDRAM support (j3 connector), allows user to select between mister and sipeed SDRAM module --- .../platforms/sipeed_tang_primer_25k.py | 52 ++++++++++++++ .../targets/sipeed_tang_primer_25k.py | 67 +++++++++++++++++-- 2 files changed, 114 insertions(+), 5 deletions(-) diff --git a/litex_boards/platforms/sipeed_tang_primer_25k.py b/litex_boards/platforms/sipeed_tang_primer_25k.py index 0263a97..6d13fa0 100644 --- a/litex_boards/platforms/sipeed_tang_primer_25k.py +++ b/litex_boards/platforms/sipeed_tang_primer_25k.py @@ -126,6 +126,57 @@ _dock_connectors = [ }), ] +# SDRAMs ------------------------------------------------------------------------------------------- + +def misterSDRAM(conn="j3"): + return [ + ("sdram_clock", 0, Pins(f"{conn}:20"), + IOStandard("LVCMOS33"), + Misc("PULL_MODE=NONE DRIVE=16"), + ), + ("sdram", 0, + Subsignal("a", Pins( + f"{conn}:37 {conn}:38 {conn}:39 {conn}:40 {conn}:28 {conn}:25 {conn}:26 {conn}:23", + f"{conn}:24 {conn}:21 {conn}:36 {conn}:22 {conn}:19") + ), + Subsignal("dq", Pins( + f"{conn}:1 {conn}:2 {conn}:3 {conn}:4 {conn}:5 {conn}:6 {conn}:7 {conn}:8", + f"{conn}:18 {conn}:17 {conn}:16 {conn}:15 {conn}:14 {conn}:13 {conn}:10 {conn}:9") + ), + Subsignal("ba", Pins(f"{conn}:34 {conn}:35")), + Subsignal("cas_n", Pins(f"{conn}:31")), + Subsignal("cs_n", Pins(f"{conn}:33")), + Subsignal("ras_n", Pins(f"{conn}:32")), + Subsignal("we_n", Pins(f"{conn}:27")), + IOStandard("LVCMOS33"), + ), + ] + +def sipeedSDRAM(conn="j3"): + return [ + ("sdram_clock", 0, Pins(f"{conn}:20"), + IOStandard("LVCMOS33"), + Misc("PULL_MODE=NONE DRIVE=16"), + ), + ("sdram", 0, + Subsignal("a", Pins( + f"{conn}:37 {conn}:38 {conn}:39 {conn}:40 {conn}:28 {conn}:25 {conn}:26 {conn}:23", + f"{conn}:24 {conn}:21 {conn}:36 {conn}:22 {conn}:19") + ), + Subsignal("dq", Pins( + f"{conn}:1 {conn}:2 {conn}:3 {conn}:4 {conn}:5 {conn}:6 {conn}:7 {conn}:8", + f"{conn}:18 {conn}:17 {conn}:16 {conn}:15 {conn}:14 {conn}:13 {conn}:10 {conn}:9"), + ), + Subsignal("ba", Pins(f"{conn}:34 {conn}:35")), + Subsignal("cas_n", Pins(f"{conn}:31")), + Subsignal("cs_n", Pins(f"{conn}:33")), + Subsignal("ras_n", Pins(f"{conn}:32")), + Subsignal("we_n", Pins(f"{conn}:27")), + Subsignal("dm", Pins(f"{conn}:29 {conn}:30")), + IOStandard("LVCMOS33"), + ), + ] + # Platform ----------------------------------------------------------------------------------------- class Platform(GowinPlatform): @@ -139,6 +190,7 @@ class Platform(GowinPlatform): self.add_connector(_dock_connectors) self.toolchain.options["use_mspi_as_gpio"] = 1 # spi flash + self.toolchain.options["use_i2c_as_gpio"] = 1 # SDRAM / J3 self.toolchain.options["use_ready_as_gpio"] = 1 # led self.toolchain.options["use_done_as_gpio"] = 1 # led self.toolchain.options["use_cpu_as_gpio"] = 1 # clk diff --git a/litex_boards/targets/sipeed_tang_primer_25k.py b/litex_boards/targets/sipeed_tang_primer_25k.py index acbf32b..a31e68c 100755 --- a/litex_boards/targets/sipeed_tang_primer_25k.py +++ b/litex_boards/targets/sipeed_tang_primer_25k.py @@ -10,21 +10,32 @@ from migen import * from litex.gen import * +from litex.build.io import DDROutput + from litex.soc.cores.clock.gowin_gw5a import GW5APLL from litex.soc.integration.soc_core import * from litex.soc.integration.builder import * from litex.soc.cores.led import LedChaser from litex.soc.cores.gpio import GPIOIn +from litedram.modules import AS4C32M16, W9825G6KH6 +from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY + from litex_boards.platforms import sipeed_tang_primer_25k # CRG ---------------------------------------------------------------------------------------------- class _CRG(LiteXModule): - def __init__(self, platform, sys_clk_freq): + def __init__(self, platform, sys_clk_freq, with_sdram=False, sdram_rate="1:2"): self.rst = Signal() self.cd_sys = ClockDomain() self.cd_por = ClockDomain() + if with_sdram: + if sdram_rate == "1:2": + self.cd_sys2x = ClockDomain() + self.cd_sys2x_ps = ClockDomain() + else: + self.cd_sys_ps = ClockDomain() # # # @@ -46,6 +57,17 @@ class _CRG(LiteXModule): pll.register_clkin(clk50, 50e6) pll.create_clkout(self.cd_sys, sys_clk_freq) + # SDRAM clock + if with_sdram: + if sdram_rate == "1:2": + pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq) + pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180) + sdram_clk = ClockSignal("sys2x_ps") + else: + pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=90) + sdram_clk = ClockSignal("sys_ps") + self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk) + # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): @@ -53,16 +75,43 @@ class BaseSoC(SoCCore): with_spi_flash = False, with_led_chaser = True, with_buttons = True, + with_sdram = False, + sdram_model = "sipeed", + sdram_rate = "1:2", **kwargs): platform = sipeed_tang_primer_25k.Platform(toolchain="gowin") + assert not with_sdram or (sdram_model in ["sipeed", "mister"]) + + if with_sdram: + platform.add_extension({ + "sipeed": sipeed_tang_primer_25k.sipeedSDRAM(), + "mister": sipeed_tang_primer_25k.misterSDRAM}[sdram_model] + ) + # CRG -------------------------------------------------------------------------------------- - self.crg = _CRG(platform, sys_clk_freq) + self.crg = _CRG(platform, sys_clk_freq, with_sdram, sdram_rate) # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Tang Primer 25K", **kwargs) + # SDR SDRAM -------------------------------------------------------------------------------- + if with_sdram and not self.integrated_main_ram_size: + module_cls = { + "sipeed": W9825G6KH6, + "mister": AS4C32M16}[sdram_model] + if sdram_rate == "1:2": + sdrphy_cls = HalfRateGENSDRPHY + else: + sdrphy_cls = GENSDRPHY + self.sdrphy = sdrphy_cls(platform.request("sdram"), sys_clk_freq) + self.add_sdram("sdram", + phy = self.sdrphy, + module = module_cls(sys_clk_freq, sdram_rate), + l2_cache_size = kwargs.get("l2_size", 8192) + ) + # SPI Flash -------------------------------------------------------------------------------- if with_spi_flash: from litespi.modules import W25Q64FV as SpiFlashModule @@ -86,14 +135,22 @@ class BaseSoC(SoCCore): def main(): from litex.build.parser import LiteXArgumentParser parser = LiteXArgumentParser(platform=sipeed_tang_primer_25k.Platform, description="LiteX SoC on Tang Primer 25K.") - parser.add_target_argument("--flash", action="store_true", help="Flash Bitstream.") - parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.") - parser.add_target_argument("--with-spi-flash", action="store_true", help="Enable SPI Flash (MMAPed).") + parser.add_target_argument("--flash", action="store_true", help="Flash Bitstream.") + parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.") + parser.add_target_argument("--with-spi-flash", action="store_true", help="Enable SPI Flash (MMAPed).") + parser.add_target_argument("--with-sdram", action="store_true", help="Enable optional SDRAM module.") + parser.add_target_argument("--sdram-model", default="sipeed", help="SDRAM module model.", + choices=[ + "sipeed", + "mister" + ]) args = parser.parse_args() soc = BaseSoC( sys_clk_freq = args.sys_clk_freq, with_spi_flash = args.with_spi_flash, + with_sdram = args.with_sdram, + sdram_model = args.sdram_model, **parser.soc_argdict ) builder = Builder(soc, **parser.builder_argdict)