From 9ae224a2a75521287be8d8a791c620c0ad28d7b3 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Mon, 16 Oct 2023 21:47:02 +0200 Subject: [PATCH] sipeed_tang_primer_25k: new board --- .../platforms/sipeed_tang_primer_25k.py | 152 ++++++++++++++++++ .../targets/sipeed_tang_primer_25k.py | 108 +++++++++++++ 2 files changed, 260 insertions(+) create mode 100644 litex_boards/platforms/sipeed_tang_primer_25k.py create mode 100755 litex_boards/targets/sipeed_tang_primer_25k.py diff --git a/litex_boards/platforms/sipeed_tang_primer_25k.py b/litex_boards/platforms/sipeed_tang_primer_25k.py new file mode 100644 index 000000000..cd90baefe --- /dev/null +++ b/litex_boards/platforms/sipeed_tang_primer_25k.py @@ -0,0 +1,152 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2023 Gwenhael Goavec-Merou +# SPDX-License-Identifier: BSD-2-Clause + +from migen import * + +from litex.build.generic_platform import * +from litex.build.gowin.platform import GowinPlatform +from litex.build.openfpgaloader import OpenFPGALoader + + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # Clk / Rst. + ("clk50", 0, Pins("E2"), IOStandard("LVCMOS33")), + + # SPIFlash. + ("spiflash", 0, + Subsignal("cs_n", Pins("E6"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("E7"), IOStandard("LVCMOS33")), + Subsignal("mosi", Pins("D6"), IOStandard("LVCMOS33")), + Subsignal("miso", Pins("E5"), IOStandard("LVCMOS33")), + Subsignal("wp", Pins("D5"), IOStandard("LVCMOS33")), + Subsignal("hold", Pins("E4"), IOStandard("LVCMOS33")), + ), + ("spiflashx4", 0, + Subsignal("cs_n", Pins("E6"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("E7"), IOStandard("LVCMOS33")), + Subsignal("dq", Pins("D6 E5 D5 E4"), IOStandard("LVCMOS33")), + ), +] + +# Dock 204 Pins SODIMM Connector ------------------------------------------------------------------- + +_connectors = [ + ["J1", + # ------------------------------------------------- + "---", # 0 + # GND GND ( 1-10). + " --- --- L9 H5 K9 J5 J8 L5 K8 K5", + # GND (11-20). + " F7 H8 F6 H7 --- G7 E8 G8 B3 F5", + # 3V3 3V3 GND GND 3V3 (21-30). + " C3 G5 E3 --- D7 --- --- --- --- L6", + # 3V3 (31-40). + " --- K6 J11 K7 J10 J7 H11 L7 H10 L8", + # GND GND (41-50). + " G11 L10 G10 K10 --- K11 D11 L11 D10 ---", + # GND GND (51-60). + " C11 E11 C10 E10 B11 A11 B10 A10 --- ---", + ], + ["J2", + # ---------------------------------------------------------------------- + "---", # 0 + # GND 3V3 3V3 ( 1-10). + " --- --- B2 --- C2 L2 F2 L1 F1 K1", + # GND (11-20). + " A1 K2 D8 J4 E1 K4 D1 G2 --- G1", + # TCK TMS TDO TDI GND (21-30). + " C1 L4 B1 L3 A2 J1 A3 J2 --- G4", + # GND 1V8 1V8 (31-40). + " M0_D3_P H4 M0_D3_N H1 --- H2 M0_D2_P --- M0_D2_N ---", + # GND 2V5 2V5 3V3 GND 3V3 3V3 (41-50). + " --- --- M0_CK_P --- M0_CK_N --- --- --- M0_D1_P ---", + # 5V GND GND 5V 5V GND 5V (51-60). + " M0_D1_N --- --- --- M0_D0_P --- M0_D0_N --- --- ---", + ], +] + +# Dock IOs ----------------------------------------------------------------------------------------- + +_dock_io = [ + # Serial. + ("serial", 0, + Subsignal("rx", Pins("J1:20")), + Subsignal("tx", Pins("J1:19")), + IOStandard("LVCMOS33") + ), + + # Leds. + ("led", 0, Pins("J1:17"), IOStandard("LVCMOS33")), # Pin READY. + ("led", 1, Pins("J1:25"), IOStandard("LVCMOS33")), # Pin DONE. + + # Buttons. + ("btn_n", 0, Pins("J1:37"), IOStandard("LVCMOS33")), + ("btn_n", 1, Pins("J1:39"), IOStandard("LVCMOS33")), + + # USB. + ("usb", 0, + Subsignal("d_p", Pins("J1:30")), + Subsignal("d_n", Pins("J1:32")), + IOStandard("LVCMOS33"), + ), +] + +_dock_connectors = [ + # Pmod + ("j4", "G11 D11 B11 C11 G10 D10 B10 C10"), + ("j5", "A11 E11 K11 L5 A10 E10 L11 K5"), + ("j6", " F5 G7 H8 H5 G5 G8 H7 J5"), + + ("j3", { + 1: "K2", 2: "K1", + 3: "L1", 4: "L2", + 5: "K4", 6: "J4", + 7: "G1", 8: "G2", + 9: "L3", 10: "L4", + 11: "---", 12: "---", + 13: "C2", 14: "B2", + 15: "F1", 16: "F2", + 17: "A1", 18: "E1", + 19: "D1", 20: "E3", + 21: "J2", 22: "J1", + 23: "H4", 24: "G4", + 25: "H2", 26: "H1", + 27: "J7", 28: "K7", + 29: "L8", 30: "L7", + 31: "K10", 32: "L10", + 33: "K9", 34: "L9", + 35: "K8", 36: "J8", + 37: "F6", 38: "F7", + 39: "J10", 40: "J11", + }), +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(GowinPlatform): + default_clk_name = "clk50" + default_clk_period = 1e9/50e6 + + def __init__(self, toolchain="gowin"): + + GowinPlatform.__init__(self, "GW5A-LV25MG121NC1/I0", _io, _connectors, toolchain=toolchain, devicename="GW5A-25A") + self.add_extension(_dock_io) + self.add_connector(_dock_connectors) + + self.toolchain.options["use_mspi_as_gpio"] = 1 # spi flash + 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 + self.toolchain.options["rw_check_on_ram"] = 1 + + def create_programmer(self, kit="openfpgaloader"): + return OpenFPGALoader(cable="ft2232") + + def do_finalize(self, fragment): + GowinPlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6) diff --git a/litex_boards/targets/sipeed_tang_primer_25k.py b/litex_boards/targets/sipeed_tang_primer_25k.py new file mode 100755 index 000000000..acbf32b57 --- /dev/null +++ b/litex_boards/targets/sipeed_tang_primer_25k.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2023 Gwenhael Goavec-Merou +# SPDX-License-Identifier: BSD-2-Clause + +from migen import * + +from litex.gen import * + +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 litex_boards.platforms import sipeed_tang_primer_25k + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(LiteXModule): + def __init__(self, platform, sys_clk_freq): + self.rst = Signal() + self.cd_sys = ClockDomain() + self.cd_por = ClockDomain() + + # # # + + # Clk + clk50 = platform.request("clk50") + + # Power on reset + por_count = Signal(16, reset=2**16-1) + por_done = Signal() + self.comb += [ + self.cd_por.clk.eq(clk50), + por_done.eq(por_count == 0), + ] + self.sync.por += If(~por_done, por_count.eq(por_count - 1)) + + # PLL + self.pll = pll = GW5APLL(devicename=platform.devicename, device=platform.device) + self.comb += pll.reset.eq(~por_done | self.rst) + pll.register_clkin(clk50, 50e6) + pll.create_clkout(self.cd_sys, sys_clk_freq) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=50e6, + with_spi_flash = False, + with_led_chaser = True, + with_buttons = True, + **kwargs): + + platform = sipeed_tang_primer_25k.Platform(toolchain="gowin") + + # CRG -------------------------------------------------------------------------------------- + self.crg = _CRG(platform, sys_clk_freq) + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Tang Primer 25K", **kwargs) + + # SPI Flash -------------------------------------------------------------------------------- + if with_spi_flash: + from litespi.modules import W25Q64FV as SpiFlashModule + from litespi.opcodes import SpiNorFlashOpCodes as Codes + self.add_spi_flash(mode="1x", module=SpiFlashModule(Codes.READ_1_1_1)) + + # Leds ------------------------------------------------------------------------------------- + if with_led_chaser: + self.leds = LedChaser( + pads = platform.request_all("led"), + sys_clk_freq = sys_clk_freq + ) + + # Buttons ---------------------------------------------------------------------------------- + if with_buttons: + self.buttons = GPIOIn(pads=~platform.request_all("btn_n")) + + +# Build -------------------------------------------------------------------------------------------- + +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).") + args = parser.parse_args() + + soc = BaseSoC( + sys_clk_freq = args.sys_clk_freq, + with_spi_flash = args.with_spi_flash, + **parser.soc_argdict + ) + builder = Builder(soc, **parser.builder_argdict) + if args.build: + builder.build(**parser.toolchain_argdict) + + if args.load: + prog = soc.platform.create_programmer() + prog.load_bitstream(builder.get_bitstream_filename(mode="sram")) + +if __name__ == "__main__": + main()