From e699c377a57f40d52da1b980b462e9570b35789d Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sat, 22 Jan 2022 11:45:49 +0800 Subject: [PATCH] sipeed_tang_nano_9k: new board Signed-off-by: Icenowy Zheng --- litex_boards/platforms/sipeed_tang_nano_9k.py | 83 +++++++++++++ litex_boards/targets/sipeed_tang_nano_9k.py | 115 ++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 litex_boards/platforms/sipeed_tang_nano_9k.py create mode 100755 litex_boards/targets/sipeed_tang_nano_9k.py diff --git a/litex_boards/platforms/sipeed_tang_nano_9k.py b/litex_boards/platforms/sipeed_tang_nano_9k.py new file mode 100644 index 0000000..966cb1f --- /dev/null +++ b/litex_boards/platforms/sipeed_tang_nano_9k.py @@ -0,0 +1,83 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +# Board diagram/pinout: +# http://www.fabienm.eu/flf/wp-content/uploads/2021/08/Tang-Nano-4K-specifications.jpg +# http://www.fabienm.eu/flf/wp-content/uploads/2021/08/Tang-Nano-4K-GW1NSR-4C-FPGA-board-pinout-diagram.jpg + + +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 + ("clk27", 0, Pins("52"), IOStandard("LVCMOS33")), + + # Leds + ("user_led", 0, Pins("10"), IOStandard("LVCMOS18")), + ("user_led", 1, Pins("11"), IOStandard("LVCMOS18")), + ("user_led", 2, Pins("13"), IOStandard("LVCMOS18")), + ("user_led", 3, Pins("14"), IOStandard("LVCMOS18")), + ("user_led", 4, Pins("15"), IOStandard("LVCMOS18")), + ("user_led", 5, Pins("16"), IOStandard("LVCMOS18")), + + # Buttons. + ("user_btn", 0, Pins("3"), IOStandard("LVCMOS18")), + ("user_btn", 1, Pins("4"), IOStandard("LVCMOS18")), + + # Serial + ("serial", 0, + Subsignal("rx", Pins("18")), + Subsignal("tx", Pins("17")), + IOStandard("LVCMOS33") + ), + + # SPIFlash + ("spiflash", 0, + Subsignal("cs_n", Pins("60"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("59"), IOStandard("LVCMOS33")), + Subsignal("miso", Pins("62"), IOStandard("LVCMOS33")), + Subsignal("mosi", Pins("61"), IOStandard("LVCMOS33")), + ), + + ("spisdcard", 0, + Subsignal("clk", Pins("36")), + Subsignal("mosi", Pins("37")), + Subsignal("cs_n", Pins("38")), + Subsignal("miso", Pins("39")), + IOStandard("LVCMOS33"), + ), + + # TODO: SPI/RGB LCD, copackaged PSRAM +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + # TODO +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(GowinPlatform): + default_clk_name = "clk27" + default_clk_period = 1e9/27e6 + + def __init__(self): + GowinPlatform.__init__(self, "GW1NR-LV9QN88PC6/I5", _io, _connectors, toolchain="gowin", devicename="GW1NR-9C") + self.toolchain.options["use_mspi_as_gpio"] = 1 + + def create_programmer(self): + 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_nano_9k.py b/litex_boards/targets/sipeed_tang_nano_9k.py new file mode 100755 index 0000000..f09b455 --- /dev/null +++ b/litex_boards/targets/sipeed_tang_nano_9k.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2022 Icenowy Zheng +# SPDX-License-Identifier: BSD-2-Clause + +import os +import argparse + +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_nano_9k + +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() + + # # # + + # Clk / Rst + clk27 = platform.request("clk27") + rst_n = platform.request("user_btn", 0) + + # PLL + self.submodules.pll = pll = GW1NPLL(devicename=platform.devicename, device=platform.device) + self.comb += pll.reset.eq(~rst_n) + pll.register_clkin(clk27, 27e6) + pll.create_clkout(self.cd_sys, sys_clk_freq) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=int(27e6), bios_flash_offset=0x0, + with_led_chaser=True, **kwargs): + platform = tang_nano_9k.Platform() + + # Disable Integrated ROM + kwargs["integrated_rom_size"] = 0 + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on Tang Nano 9K", + **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # SPI Flash -------------------------------------------------------------------------------- + from litespi.modules import W25Q32 + from litespi.opcodes import SpiNorFlashOpCodes as Codes + self.add_spi_flash(mode="1x", module=W25Q32(Codes.READ_1_1_1), with_master=False) + + # Add ROM linker region -------------------------------------------------------------------- + self.bus.add_region("rom", SoCRegion( + origin = self.bus.regions["spiflash"].origin + bios_flash_offset, + size = 64*kB, + linker = True) + ) + self.cpu.set_reset_address(self.bus.regions["rom"].origin) + + # Leds ------------------------------------------------------------------------------------- + if with_led_chaser: + self.submodules.leds = LedChaser( + pads = platform.request_all("user_led"), + sys_clk_freq = sys_clk_freq) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on Tang Nano 9K") + parser.add_argument("--build", action="store_true", help="Build bitstream.") + parser.add_argument("--load", action="store_true", help="Load bitstream.") + parser.add_argument("--flash", action="store_true", help="Flash Bitstream.") + parser.add_argument("--sys-clk-freq",default=27e6, help="System clock frequency.") + parser.add_argument("--bios-flash-offset", default="0x0", help="BIOS offset in SPI Flash.") + builder_args(parser) + soc_core_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + sys_clk_freq=int(float(args.sys_clk_freq)), + bios_flash_offset=int(args.bios_flash_offset, 0), + **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(os.path.join(builder.gateware_dir, "impl", "pnr", "project.fs")) + + if args.flash: + prog = soc.platform.create_programmer() + prog.flash(0, os.path.join(builder.gateware_dir, "impl", "pnr", "project.fs")) + prog.flash(int(args.bios_flash_offset, 0), "build/sipeed_tang_nano_9k/software/bios/bios.bin", external=True) + +if __name__ == "__main__": + main()