#!/usr/bin/env python3 # # neopixelar.py # # This file has been derived from LiteX-Boards/colorlight_5b_75x.py # Copyright (c) 2020 Florent Kermarrec # SPDX-License-Identifier: BSD-2-Clause # # Disclaimer: Still a proof of concept with large timings violations on the IP/UDP and # Etherbone stack that need to be optimized. It was initially just used to validate the reversed # pinout but happens to work on hardware... # # History: # -------- # 14.09.20/KQ Initial version, some output ports activated (user_led, J4) for testing # 15.09.20/KQ Own logic exported to external module (neopixelprotocol.py - now neopixelengine.py) # 19.09.20/KQ Project renamed 'NeoPixelar' (swedish plural for NeoPixel ...) # 20.11.20/KQ Input provided: U28 -> J1 (1, 2, 3, [4=GND], 5, 6, 7), J2 (1, 2, [4=GND]) # (U15 -> J7 ([4=GND], 5, 7), J8 (1, 2, 3, [4=GND], 5, 6, 7)) # 02.01.21/KQ DMA DRAM access integration started # # Build/Use ---------------------------------------------------------------------------------------- # - 'python3 neopixelar.py --build --revision=7.0 --uart-name=crossover --with-etherbone --ip-address=192.168.1.20 --csr-csv=build/csr.csv' # to generate # - 'python3 neopixelar.py --load' to download to FPGA # - 'ping 192.168.1.20' to verify ethernet connection - via LEFT(!) RJ45 port # - 'wishbone-tool --ethernet-host 192.168.1.20 --server terminal --csr-csv build/csr.csv' # You should see the LiteX BIOS and be able to interact with it # - To load a file to RAM (@0x40000000 len=0x400000) use: # wishbone-tool --ethernet-host 192.168.1.20 --server load-file --csr-csv build/csr.csv # --load-address 0x40000000 # --load-name build/colorlight_5a_75b/software/ # To disassemble raw file: # ../fpga/litex/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-objdump # -D -b binary ./build/colorlight_5a_75b/software/bios/bios.bin -m riscv # import os import argparse import sys from migen import * from migen.genlib.misc import WaitTimer from migen.genlib.resetsync import AsyncResetSynchronizer from litex.build.io import DDROutput from litex_boards.platforms import colorlight_5a_75b from litex.build.lattice.trellis import trellis_args, trellis_argdict from litex.soc.cores.clock import * from litex.soc.cores.spi_flash import ECP5SPIFlash from litex.soc.cores.gpio import GPIOOut from litex.soc.integration.soc_core import * from litex.soc.integration.builder import * from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage, CSRField from litex.soc.interconnect.stream import SyncFIFO from litedram.modules import M12L16161A, M12L64322A from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY from litedram.frontend.dma import LiteDRAMDMAReader, LiteDRAMDMAWriter from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII from litex.build.generic_platform import * import litex.soc.doc as lxsocdoc # KQ's helper modules ... from libmodules.systime import SysTime from libmodules.dramtransfer import DRAMTransfer from neopixelengine import NeoPixelEngine from helpers.prepare_firmware import copyjob # Explicit IO naming, taken from board colorlight 5a 75b board defs. (rev. 7.0) # from https://github.com/q3k/chubby75/blob/master/5a-75b/hardware_V7.0.md #_connectors_v7_0 = [ # ("j1", "F3 F1 G3 - G2 H3 H5 F15 L2 K1 J5 K2 B16 J14 F12 -"), # ("j2", "J4 K3 G1 - K4 C2 E3 F15 L2 K1 J5 K2 B16 J14 F12 -"), # ("j3", "H4 K5 P1 - R1 L5 F2 F15 L2 K1 J5 K2 B16 J14 F12 -"), # ("j4", "P4 R2 M8 - M9 T6 R6 F15 L2 K1 J5 K2 B16 J14 F12 -"), # ("j5", "M11 N11 P12 - K15 N12 L16 F15 L2 K1 J5 K2 B16 J14 F12 -"), # ("j6", "K16 J15 J16 - J12 H15 G16 F15 L2 K1 J5 K2 B16 J14 F12 -"), # ("j7", "H13 J13 H12 - G14 H14 G15 F15 L2 K1 J5 K2 B16 J14 F12 -"), # ("j8", "A15 F16 A14 - E13 B14 A13 F15 L2 K1 J5 K2 B16 J14 F12 -"), #] _gpios = [ # Attn. Jx/pin descriptions are 1-based, but zero based defs. used! # J1 ("gpio", 0, Pins("j1:0"), IOStandard("LVCMOS33")), # Input now ("gpio", 1, Pins("j1:1"), IOStandard("LVCMOS33")), # Input now ("gpio", 2, Pins("j1:2"), IOStandard("LVCMOS33")), # Input now # GND ("gpio", 3, Pins("j1:4"), IOStandard("LVCMOS33")), # Input now ("gpio", 4, Pins("j1:5"), IOStandard("LVCMOS33")), # Input now ("gpio", 5, Pins("j1:6"), IOStandard("LVCMOS33")), # Input now ("gpio", 6, Pins("j1:7"), IOStandard("LVCMOS33")), ("gpio", 7, Pins("j1:8"), IOStandard("LVCMOS33")), ("gpio", 8, Pins("j1:9"), IOStandard("LVCMOS33")), ("gpio", 9, Pins("j1:10"), IOStandard("LVCMOS33")), ("gpio", 10, Pins("j1:11"), IOStandard("LVCMOS33")), ("gpio", 11, Pins("j1:12"), IOStandard("LVCMOS33")), ("gpio", 12, Pins("j1:13"), IOStandard("LVCMOS33")), ("gpio", 13, Pins("j1:14"), IOStandard("LVCMOS33")), # GND # J2 ("gpio", 14, Pins("j2:0"), IOStandard("LVCMOS33")), # Input now ("gpio", 15, Pins("j2:1"), IOStandard("LVCMOS33")), # Input now ("gpio", 16, Pins("j2:2"), IOStandard("LVCMOS33")), # GND ("gpio", 17, Pins("j2:4"), IOStandard("LVCMOS33")), ("gpio", 18, Pins("j2:5"), IOStandard("LVCMOS33")), ("gpio", 19, Pins("j2:6"), IOStandard("LVCMOS33")), ("gpio", 20, Pins("j2:7"), IOStandard("LVCMOS33")), ("gpio", 21, Pins("j2:8"), IOStandard("LVCMOS33")), ("gpio", 22, Pins("j2:9"), IOStandard("LVCMOS33")), ("gpio", 23, Pins("j2:10"), IOStandard("LVCMOS33")), ("gpio", 24, Pins("j2:11"), IOStandard("LVCMOS33")), ("gpio", 25, Pins("j2:12"), IOStandard("LVCMOS33")), ("gpio", 26, Pins("j2:13"), IOStandard("LVCMOS33")), ("gpio", 27, Pins("j2:14"), IOStandard("LVCMOS33")), # GND # J3 ("gpio", 28, Pins("j3:0"), IOStandard("LVCMOS33")), ("gpio", 29, Pins("j3:1"), IOStandard("LVCMOS33")), ("gpio", 30, Pins("j3:2"), IOStandard("LVCMOS33")), # GND ("gpio", 31, Pins("j3:4"), IOStandard("LVCMOS33")), ("gpio", 32, Pins("j3:5"), IOStandard("LVCMOS33")), ("gpio", 33, Pins("j3:6"), IOStandard("LVCMOS33")), ("gpio", 34, Pins("j3:7"), IOStandard("LVCMOS33")), ("gpio", 35, Pins("j3:8"), IOStandard("LVCMOS33")), ("gpio", 36, Pins("j3:9"), IOStandard("LVCMOS33")), ("gpio", 37, Pins("j3:10"), IOStandard("LVCMOS33")), ("gpio", 38, Pins("j3:11"), IOStandard("LVCMOS33")), ("gpio", 39, Pins("j3:12"), IOStandard("LVCMOS33")), ("gpio", 40, Pins("j3:13"), IOStandard("LVCMOS33")), ("gpio", 41, Pins("j3:14"), IOStandard("LVCMOS33")), # GND # J4 ("gpio", 42, Pins("j4:0"), IOStandard("LVCMOS33")), # j4 pin 1 ("gpio", 43, Pins("j4:1"), IOStandard("LVCMOS33")), # j4 pin 2 ("gpio", 44, Pins("j4:2"), IOStandard("LVCMOS33")), # j4 pin 3 # j4 pin 4, GND ("gpio", 45, Pins("j4:4"), IOStandard("LVCMOS33")), # j4 pin 5 ("gpio", 46, Pins("j4:5"), IOStandard("LVCMOS33")), # j4 pin 6 ("gpio", 47, Pins("j4:6"), IOStandard("LVCMOS33")), # j4 pin 7 ("gpio", 48, Pins("j4:7"), IOStandard("LVCMOS33")), # j4 pin 8 ("gpio", 49, Pins("j4:8"), IOStandard("LVCMOS33")), # j4 pin 9 ("gpio", 50, Pins("j4:9"), IOStandard("LVCMOS33")), # j4 pin 10 ("gpio", 51, Pins("j4:10"), IOStandard("LVCMOS33")), # j4 pin 11 ("gpio", 52, Pins("j4:11"), IOStandard("LVCMOS33")), # j4 pin 12 ("gpio", 53, Pins("j4:12"), IOStandard("LVCMOS33")), # j4 pin 13 ("gpio", 54, Pins("j4:13"), IOStandard("LVCMOS33")), # j4 pin 14 ("gpio", 55, Pins("j4:14"), IOStandard("LVCMOS33")), # j4 pin 15 # j4 pin 16, GND # J5 ("gpio", 56, Pins("j5:0"), IOStandard("LVCMOS33")), ("gpio", 57, Pins("j5:1"), IOStandard("LVCMOS33")), ("gpio", 58, Pins("j5:2"), IOStandard("LVCMOS33")), # GND ("gpio", 59, Pins("j5:4"), IOStandard("LVCMOS33")), ("gpio", 60, Pins("j5:5"), IOStandard("LVCMOS33")), ("gpio", 61, Pins("j5:6"), IOStandard("LVCMOS33")), ("gpio", 62, Pins("j5:7"), IOStandard("LVCMOS33")), ("gpio", 63, Pins("j5:8"), IOStandard("LVCMOS33")), ("gpio", 64, Pins("j5:9"), IOStandard("LVCMOS33")), ("gpio", 65, Pins("j5:10"), IOStandard("LVCMOS33")), ("gpio", 66, Pins("j5:11"), IOStandard("LVCMOS33")), ("gpio", 67, Pins("j5:12"), IOStandard("LVCMOS33")), ("gpio", 68, Pins("j5:13"), IOStandard("LVCMOS33")), ("gpio", 69, Pins("j5:14"), IOStandard("LVCMOS33")), # GND # J6 ("gpio", 70, Pins("j6:0"), IOStandard("LVCMOS33")), ("gpio", 71, Pins("j6:1"), IOStandard("LVCMOS33")), ("gpio", 72, Pins("j6:2"), IOStandard("LVCMOS33")), # GND ("gpio", 73, Pins("j6:4"), IOStandard("LVCMOS33")), ("gpio", 74, Pins("j6:5"), IOStandard("LVCMOS33")), ("gpio", 75, Pins("j6:6"), IOStandard("LVCMOS33")), ("gpio", 76, Pins("j6:7"), IOStandard("LVCMOS33")), ("gpio", 77, Pins("j6:8"), IOStandard("LVCMOS33")), ("gpio", 78, Pins("j6:9"), IOStandard("LVCMOS33")), ("gpio", 79, Pins("j6:10"), IOStandard("LVCMOS33")), ("gpio", 80, Pins("j6:11"), IOStandard("LVCMOS33")), ("gpio", 81, Pins("j6:12"), IOStandard("LVCMOS33")), ("gpio", 82, Pins("j6:13"), IOStandard("LVCMOS33")), ("gpio", 83, Pins("j6:14"), IOStandard("LVCMOS33")), # GND # J7 ("gpio", 84, Pins("j7:0"), IOStandard("LVCMOS33")), ("gpio", 85, Pins("j7:1"), IOStandard("LVCMOS33")), ("gpio", 86, Pins("j7:2"), IOStandard("LVCMOS33")), # GND ("gpio", 87, Pins("j7:4"), IOStandard("LVCMOS33")), # Input now ("gpio", 88, Pins("j7:5"), IOStandard("LVCMOS33")), ("gpio", 89, Pins("j7:6"), IOStandard("LVCMOS33")), # Input now ("gpio", 90, Pins("j7:7"), IOStandard("LVCMOS33")), ("gpio", 91, Pins("j7:8"), IOStandard("LVCMOS33")), ("gpio", 92, Pins("j7:9"), IOStandard("LVCMOS33")), ("gpio", 93, Pins("j7:10"), IOStandard("LVCMOS33")), ("gpio", 94, Pins("j7:11"), IOStandard("LVCMOS33")), ("gpio", 95, Pins("j7:12"), IOStandard("LVCMOS33")), ("gpio", 96, Pins("j7:13"), IOStandard("LVCMOS33")), ("gpio", 97, Pins("j7:14"), IOStandard("LVCMOS33")), # GND # J8 ("gpio", 98, Pins("j8:0"), IOStandard("LVCMOS33")), # Input now ("gpio", 99, Pins("j8:1"), IOStandard("LVCMOS33")), # Input now ("gpio", 100, Pins("j8:2"), IOStandard("LVCMOS33")), # Input now # GND ("gpio", 101, Pins("j8:4"), IOStandard("LVCMOS33")), # Input now ("gpio", 102, Pins("j8:5"), IOStandard("LVCMOS33")), # Input now ("gpio", 103, Pins("j8:6"), IOStandard("LVCMOS33")), # Input now ("gpio", 104, Pins("j8:7"), IOStandard("LVCMOS33")), ("gpio", 105, Pins("j8:8"), IOStandard("LVCMOS33")), ("gpio", 106, Pins("j8:9"), IOStandard("LVCMOS33")), ("gpio", 107, Pins("j8:10"), IOStandard("LVCMOS33")), ("gpio", 108, Pins("j8:11"), IOStandard("LVCMOS33")), ("gpio", 109, Pins("j8:12"), IOStandard("LVCMOS33")), ("gpio", 110, Pins("j8:13"), IOStandard("LVCMOS33")), ("gpio", 111, Pins("j8:14"), IOStandard("LVCMOS33")), # GND ] # CRG ---------------------------------------------------------------------------------------------- class _CRG(Module): def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, with_rst=True, sdram_rate="1:1"): self.clock_domains.cd_sys = ClockDomain() if sdram_rate == "1:2": self.clock_domains.cd_sys2x = ClockDomain() self.clock_domains.cd_sys2x_ps = ClockDomain(reset_less=True) else: self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True) # # # # Clk / Rst if not use_internal_osc: clk = platform.request("clk25") clk_freq = 25e6 else: clk = Signal() div = 5 self.specials += Instance("OSCG", p_DIV = div, o_OSC = clk) clk_freq = 310e6/div rst_n = 1 if not with_rst else platform.request("user_btn_n", 0) # PLL self.submodules.pll = pll = ECP5PLL() self.comb += pll.reset.eq(~rst_n) pll.register_clkin(clk, clk_freq) pll.create_clkout(self.cd_sys, sys_clk_freq) 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) # Idealy 90° but needs to be increased. else: pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=180) # Idealy 90° but needs to be increased. # USB PLL if with_usb_pll: self.submodules.usb_pll = usb_pll = ECP5PLL() self.comb += usb_pll.reset.eq(~rst_n) usb_pll.register_clkin(clk, clk_freq) self.clock_domains.cd_usb_12 = ClockDomain() self.clock_domains.cd_usb_48 = ClockDomain() usb_pll.create_clkout(self.cd_usb_12, 12e6, margin=0) usb_pll.create_clkout(self.cd_usb_48, 48e6, margin=0) # SDRAM clock sdram_clk = ClockSignal("sys2x_ps" if sdram_rate == "1:2" else "sys_ps") self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk) # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): def __init__(self, board, revision, with_ethernet=False, with_etherbone=False, eth_phy=0, ip_address=None, mac_address=None, sys_clk_freq=60e6, use_internal_osc=False, sdram_rate="1:1", **kwargs): platform = colorlight_5a_75b.Platform(revision="7.0") # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, int(sys_clk_freq), ident = "LiteX SoC on Colorlight " + board.upper(), ident_version = True, **kwargs) # CRG -------------------------------------------------------------------------------------- with_rst = kwargs["uart_name"] not in ["serial", "bridge"] # serial_rx shared with user_btn_n. with_usb_pll = kwargs.get("uart_name", None) == "usb_acm" self.submodules.crg = _CRG(platform, sys_clk_freq, use_internal_osc=use_internal_osc, with_usb_pll=with_usb_pll,with_rst=with_rst, sdram_rate=sdram_rate) # SDR SDRAM -------------------------------------------------------------------------------- if not self.integrated_main_ram_size: sdrphy_cls = HalfRateGENSDRPHY if sdram_rate == "1:2" else GENSDRPHY self.submodules.sdrphy = sdrphy_cls(platform.request("sdram")) if board == "5a-75e" and revision == "6.0": sdram_cls = M12L64322A sdram_size = 0x80000000 else: sdram_cls = M12L16161A sdram_size = 0x40000000 self.add_sdram("sdram", phy = self.sdrphy, module = sdram_cls(sys_clk_freq, sdram_rate), origin = self.mem_map["main_ram"], size = kwargs.get("max_sdram_size", sdram_size), l2_cache_size = kwargs.get("l2_size", 8192), l2_cache_min_data_width = kwargs.get("min_l2_data_width", 128), l2_cache_reverse = True ) # Ethernet / Etherbone --------------------------------------------------------------------- if with_ethernet or with_etherbone: self.submodules.ethphy = LiteEthPHYRGMII( clock_pads = self.platform.request("eth_clocks", eth_phy), pads = self.platform.request("eth", eth_phy)) self.add_csr("ethphy") if with_ethernet: self.add_ethernet(phy=self.ethphy) if with_etherbone: self.add_etherbone( phy=self.ethphy, ip_address = ip_address, mac_address = mac_address, ) # Add platform specific I/O platform.add_extension(_gpios) # General LED outputs # For U28 3.3V(!) inputs: (also see separate picture) self.J1_1 = J1_1 = platform.request("gpio", 0) # Pins for logical evaluation self.J1_2 = J1_2 = platform.request("gpio", 1) self.J1_3 = J1_3 = platform.request("gpio", 2) self.J1_5 = J1_5 = platform.request("gpio", 3) self.J1_6 = J1_6 = platform.request("gpio", 4) self.J1_7 = J1_7 = platform.request("gpio", 5) self.J2_1 = J2_1 = platform.request("gpio", 14) self.J2_2 = J2_2 = platform.request("gpio", 15) ''' # For U15 (not used currently) J7_5 = Signal(1) self.comb += J7_5.eq(platform.request("gpio", 87)) J7_7 = Signal(1) self.comb += J7_7.eq(platform.request("gpio", 89)) J8_1 = Signal(1) self.comb += J8_1.eq(platform.request("gpio", 98)) J8_2 = Signal(1) self.comb += J8_2.eq(platform.request("gpio", 99)) J8_3 = Signal(1) self.comb += J8_3.eq(platform.request("gpio", 100)) J8_5 = Signal(1) self.comb += J8_5.eq(platform.request("gpio", 101)) J8_6 = Signal(1) self.comb += J8_6.eq(platform.request("gpio", 102)) J8_7 = Signal(1) self.comb += J8_7.eq(platform.request("gpio", 103)) ''' # OR it all together: Every input lights LED ... self.led_logic1 = led_logic1 = Signal(1) self.comb += led_logic1.eq(J1_1 | J1_2 | J1_3 | J1_5 | J1_6 | J1_7 | J2_1 | J2_2) #led_logic2 = Signal(1) # Not used currently #self.comb += led_logic2.eq(J8_1 | J8_2 | J8_3 | J8_5 | J8_6 | J8_7 | J7_5 | J7_7) # Base counter (used for clocking) counter = Signal(32) # 32-Bit counter self.sync += counter.eq(counter + 1) # USERLED blink (on-board LED) # only w/ uart-name=crossover option: if kwargs["uart_name"] not in ["serial", "bridge"]: self.comb += platform.request("user_led_n").eq(~(counter[23] | led_logic1)) #| led_logic2) # ~2Hz | inputs # System time (count) self.submodules.systime = systime = SysTime(comparecount=0x0000EA90) self.add_csr("systime") # DRAM test MAXWORDS = 32 # Transfer length x 32-bit, FIFO depth self.submodules.mm2s = mm2s = LiteDRAMDMAReader(self.sdram.crossbar.get_port(), fifo_depth=MAXWORDS, fifo_buffered=True) mm2s.add_csr() self.add_csr("mm2s") self.submodules.sync_fifo = sync_fifo = SyncFIFO([("data", 32)], MAXWORDS, True) self.comb += mm2s.source.connect(sync_fifo.sink) # Connect DMA-Reader.source -> FIFO.sink self.submodules.dramtransfer = DRAMTransfer(maxwords=MAXWORDS, dma_reader=mm2s, sync_fifo=sync_fifo) self.add_csr("dramtransfer") # Adjust no. for your actual project ... max_TABLES = 2 # 1..16 max_LEDS_per_chain = MAXWORDS # 1..256 self.submodules.npe = NeoPixelEngine(n_TABLES=max_TABLES, n_LEDs=max_LEDS_per_chain) self.add_csr("npe") for i in range(42,56+2): # Example: Do output on J4 (14) & J5 (2) self.comb += platform.request("gpio", i).eq(self.npe.bDataPin[i-42]) # Output data pin # Build -------------------------------------------------------------------------------------------- def main(): parser = argparse.ArgumentParser(description="LiteX SoC on Colorlight 5A-75X") builder_args(parser) soc_core_args(parser) trellis_args(parser) parser.add_argument("--build", action="store_true", help="Build bitstream") parser.add_argument("--load", action="store_true", help="Load bitstream") parser.add_argument("--board", default="5a-75b", help="Board type: 5a-75b (default) & don't change!") parser.add_argument("--revision", default="7.0", type=str, help="Board revision 7.0 (default) & don't change!") parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support") parser.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support") parser.add_argument("--eth-phy", default=0, type=int, help="Ethernet PHY 0 or 1 (default=0)") parser.add_argument("--ip-address", default="192.168.1.50", help="Ethernet IP address of the board.") parser.add_argument("--mac-address", default="0x726b895bc2e2", help="Ethernet MAC address of the board.") parser.add_argument("--sys-clk-freq", default=60e6, type=float, help="System clock frequency (default=60MHz)") parser.add_argument("--use-internal-osc", action="store_true", help="Use internal oscillator") parser.add_argument("--sdram-rate", default="1:1", help="SDRAM Rate 1:1 Full Rate (default), 1:2 Half Rate") parser.add_argument("--csr_csv", default="build/csr.csv", help="CSR list location") parser.add_argument("--doc", action="store_true", help="Create doc files for sphinx generator") parser.add_argument("--flash", action="store_true", help="Load bitstream to flash") args = parser.parse_args() #assert not (args.with_ethernet and args.with_etherbone) soc = BaseSoC(board=args.board, revision=args.revision, with_ethernet = args.with_ethernet, with_etherbone = args.with_etherbone, eth_phy = args.eth_phy, ip_address = args.ip_address, mac_address = int(args.mac_address, 0), sys_clk_freq = args.sys_clk_freq, use_internal_osc = args.use_internal_osc, sdram_rate = args.sdram_rate, **soc_core_argdict(args)) # 32MBit SPIFlash ------------------------------------------------------------------------ flashbase = 0xc0000000 flashoffset = 0x100000 # Used to be zero (default) soc.mem_map["spiflash"] = flashbase # Length: 0x01000000 ('til 0xc1000000 - 1) # Boot at +1MB soc.add_constant("FLASH_BOOT_ADDRESS", soc.mem_map["spiflash"] + 1024*1024) # 0xc0100000 soc.add_spi_flash(name="spiflash", mode="1x", dummy_cycles=8, clk_freq=5e6) builder = Builder(soc, **builder_argdict(args)) # Now override boot address (used to be zero/default) args.ecppack_bootaddr = flashbase + flashoffset # 0xC0100000 builder.build(**trellis_argdict(args), run=args.build) # Written here to (local) build tree if args.doc: print("Generating documentation for sphinx ...") lxsocdoc.generate_docs(soc, "build/documentation/", project_name="neopixelar", author="KQ") print("Generate via: 'sphinx-build -b html build/documentation build/documentation/html'") if args.load: prog = soc.platform.create_programmer() prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".svf")) return if args.flash: # Convert Bit File to Jtag Write Flash command name = os.path.join(builder.gateware_dir, soc.build_name) print(f"Executing ./bit_to_flash.py {name}.bit {name}.svf.flash") from helpers.bit_to_flash import convertBitToFlashFile convertBitToFlashFile(name + ".bit", name + ".svf.flash", address=0) from helpers.load_to_flash import load2flash load2flash(name + ".svf.flash") return if __name__ == "__main__": copyjob() # Create backup if nec. & move our firmware to the correct location main() # Maybe revoke backup action here ...