From b97d9cd9e87ea809e6977d6b92eb196a9edb2dc1 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 3 Jun 2022 00:24:20 +0800 Subject: [PATCH] sipeed_tang_primer_20k: new board Only initial support is added. Signed-off-by: Icenowy Zheng --- .../platforms/sipeed_tang_primer_20k.py | 77 +++++++++++++++ .../targets/sipeed_tang_primer_20k.py | 98 +++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 litex_boards/platforms/sipeed_tang_primer_20k.py create mode 100755 litex_boards/targets/sipeed_tang_primer_20k.py diff --git a/litex_boards/platforms/sipeed_tang_primer_20k.py b/litex_boards/platforms/sipeed_tang_primer_20k.py new file mode 100644 index 0000000..904192d --- /dev/null +++ b/litex_boards/platforms/sipeed_tang_primer_20k.py @@ -0,0 +1,77 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2022 Icenowy Zheng +# 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.gowin.programmer import GowinProgrammer +from litex.build.openfpgaloader import OpenFPGALoader + + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # Clk / Rst + ("clk27", 0, Pins("H11"), IOStandard("LVCMOS33")), + + # Serial + ("serial", 0, + Subsignal("rx", Pins("T13")), + Subsignal("tx", Pins("M11")), + IOStandard("LVCMOS33") + ), + + # SPIFlash + ("spiflash", 0, + Subsignal("cs_n", Pins("M9"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("L10"), IOStandard("LVCMOS33")), + Subsignal("miso", Pins("P10"), IOStandard("LVCMOS33")), + Subsignal("mosi", Pins("R10"), IOStandard("LVCMOS33")), + ), + + ## sdcard connector + ("spisdcard", 0, + Subsignal("clk", Pins("N10")), + Subsignal("mosi", Pins("R14")), + Subsignal("cs_n", Pins("N11")), + Subsignal("miso", Pins("M8")), + IOStandard("LVCMOS33"), + ), + ("sdcard", 0, + Subsignal("data", Pins("M8 M7 M10 N11")), + Subsignal("cmd", Pins("R14")), + Subsignal("clk", Pins("N10")), + Subsignal("cd", Pins("D15")), + IOStandard("LVCMOS33"), + ), + + # TODO: SPI LCD +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + # TODO +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(GowinPlatform): + default_clk_name = "clk27" + default_clk_period = 1e9/27e6 + + def __init__(self, toolchain="gowin"): + GowinPlatform.__init__(self, "GW2A-LV18PG256C8/I7", _io, _connectors, toolchain=toolchain, devicename="GW2A-18C") + self.toolchain.options["use_mspi_as_gpio"] = 1 + self.toolchain.options["use_sspi_as_gpio"] = 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("clk27", loose=True), 1e9/27e6) diff --git a/litex_boards/targets/sipeed_tang_primer_20k.py b/litex_boards/targets/sipeed_tang_primer_20k.py new file mode 100755 index 0000000..f2fc56c --- /dev/null +++ b/litex_boards/targets/sipeed_tang_primer_20k.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2022 Icenowy Zheng +# SPDX-License-Identifier: BSD-2-Clause + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex.soc.cores.clock.gowin_gw1n import GW1NPLL +from litex.soc.integration.soc_core import * +from litex.soc.integration.soc import SoCRegion +from litex.soc.integration.builder import * +from litex.soc.cores.led import LedChaser +from litex.soc.cores.video import * + +from litex_boards.platforms import tang_primer_20k + +from litex.soc.cores.hyperbus import HyperRAM + +kB = 1024 +mB = 1024*kB + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq, with_video_pll=False): + self.rst = Signal() + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_por = ClockDomain() + + # # # + + # Clk + clk27 = platform.request("clk27") + + # PLL + self.submodules.pll = pll = GW1NPLL(devicename=platform.devicename, device=platform.device) + pll.register_clkin(clk27, 27e6) + pll.create_clkout(self.cd_sys, sys_clk_freq) + + # Power on reset (the onboard POR is not aware of reprogramming) + por_count = Signal(16, reset=2**16-1) + por_done = Signal() + self.comb += self.cd_por.clk.eq(clk27) + self.comb += por_done.eq(por_count == 0) + self.sync.por += If(~por_done, por_count.eq(por_count - 1)) + self.comb += pll.reset.eq(~por_done) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=int(48e6), **kwargs): + platform = tang_primer_20k.Platform() + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on Tang Primer 20K", + **kwargs + ) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + from litex.soc.integration.soc import LiteXSoCArgumentParser + parser = LiteXSoCArgumentParser(description="LiteX SoC on Tang Primer 20K") + target_group = parser.add_argument_group(title="Target options") + target_group.add_argument("--build", action="store_true", help="Build bitstream.") + target_group.add_argument("--load", action="store_true", help="Load bitstream.") + target_group.add_argument("--flash", action="store_true", help="Flash Bitstream.") + target_group.add_argument("--sys-clk-freq",default=48e6, help="System clock frequency.") + builder_args(parser) + soc_core_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + sys_clk_freq=int(float(args.sys_clk_freq)), + **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(builder.get_bitstream_filename(mode="sram")) + + if args.flash: + prog = soc.platform.create_programmer() + prog.flash(0, builder.get_bitstream_filename(mode="flash", ext=".fs"), external=True) + +if __name__ == "__main__": + main()