Litex System on Colorlight Board. ECP5 FPGA runs Risc-V Core and custom Hardware
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

133 lines
5.2 KiB

#!/usr/bin/env python3
# This file is Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# License: BSD
import os
import argparse
from litex.soc.cores.clock import *
from litex.soc.cores.identifier import Identifier
from litex.soc.cores.spi_flash import ECP5SPIFlash
from litex.soc.cores.gpio import GPIOOut, GPIOIn
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.build.lattice.trellis import trellis_args, trellis_argdict
from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
from litex.build.generic_platform import *
from litex_boards.targets import colorlight_5a_75x
from litex_boards.platforms import colorlight_5a_75b
from litex.build.generic_platform import *
from basic_system.hub75sender import Hub75Sender
from basic_system.bit_to_flash import convertBitToFlashFile
from basic_system.cl_full import load
import numpy as np
import cv2
ios = [
("led", 0, Pins("j4:1 j4:5"), IOStandard("LVCMOS33")),
("j3", 0, Pins("j3:1 j3:5"), IOStandard("LVCMOS33")),
("j5", 0,
Subsignal("rgb", Pins("j5:0 j5:1 j5:2 j5:4 j5:5 j5:6")),
Subsignal("adr", Pins("j5:8 j5:9 j5:10 j5:11 j5:7")),
Subsignal("clk", Pins("j5:12")),
Subsignal("lat", Pins("j5:13")),
Subsignal("oen", Pins("j5:14")),
IOStandard("LVCMOS33"))
]
def getContentFromImage(file):
"""Load image and reduce colorspace to RGG332"""
img = cv2.imread(file, 1)
r = [(i >> 0) & 0xe0 for i in img[:, :, 2]]
g = [(i >> 3) & 0x1c for i in img[:, :, 1]]
b = [(i >> 6) & 0x03 for i in img[:, :, 0]]
content = [x[0] + x[1] + x[2] for x in zip(r, g, b)]
return np.array(content, dtype='uint8').flatten()
def getContentFromSyntetic():
content = np.zeros((64, 64), dtype='uint8')
content[ 0:64, 0:64] = 0xff # White Border
content[ 2:62, 2:62] = 0b00100101 # Gray inner Border
content[ 4:60, 4:60] = 0 # Black
content[ 8:16, 8:16] = 0b00000011 # Blue
content[16:24, 16:24] = 0b11100000 # Red
content[24:32, 24:32] = 0b00011100 # Green
content[32:40, 32:40] = 0b00011111 # Cyan
content[40:48, 40:48] = 0b11100011 # Pink
content[48:56, 48:56] = 0b11111100 # Yellow
return content.flatten()
class MemTest(Module, AutoCSR):
def __init__(self):
self.specials.mem = Memory(32,128, init=(1,2,3,4))
self.specials.rdport = self.mem.get_port()
class ClMini(SoCCore):
def __init__(self, with_etherbone=False, ip=None, mac=None):
platform = colorlight_5a_75b.Platform(revision="7.0")
sys_clk_freq = int(60e6)
# SoCMini ----------------------------------------------------------------------------------
SoCMini.__init__(self, platform, clk_freq=sys_clk_freq)
self.submodules.crg = colorlight_5a_75x._CRG(platform, sys_clk_freq)
self.platform.add_extension(ios)
# Etherbone --------------------------------------------------------------------------------
if with_etherbone:
self.submodules.ethphy = LiteEthPHYRGMII(
clock_pads=self.platform.request("eth_clocks"),
pads=self.platform.request("eth"))
self.add_csr("ethphy")
self.add_etherbone(phy=self.ethphy,ip_address=ip, mac_address=mac)
#self.submodules.mymem = MemTest()
#self.add_csr("mymem_mem")
content = getContentFromSyntetic()
#content = getContentFromImage("testimage.png")
self.submodules.hub = Hub75Sender(64, 64, content, platform.request("j5"))
self.add_csr("hub_mem")
self.add_csr("hub")
self.comb += platform.request("j3").eq(Cat(self.hub.frameDone, self.hub.rowDone))
counter = Signal(32)
self.sync += counter.eq(counter + 1)
self.comb += platform.request("led").eq(counter[22:24])
# Led --------------------------------------------------------------------------------------
self.submodules.led = GPIOOut(platform.request("user_led_n"))
self.add_csr("led")
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on Colorlight 5A-75X")
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("--ip-address", default="10.42.1.222", help="Ethernet IP address of the board.")
parser.add_argument("--mac-address", default="0x726b895bc2e2", help="Ethernet MAC address of the board.")
parser.set_defaults(build=True, load=True)
args = parser.parse_args()
soc = ClMini(ip=args.ip_address, mac=int(args.mac_address, 0))
builder = Builder(soc, output_dir="build", csr_csv="scripts/csr.csv")
builder.build(build_name="clmini", run=args.build)
if args.flash: # Convert Bit File to Jtag Write Flash command
name = os.path.join(builder.gateware_dir, soc.build_name)
convertBitToFlashFile(name+".bit", name+".svf.flash")
load(name + ".svf.flash")
return
if args.load: # Temporary Load into FPGA
load(os.path.join(builder.gateware_dir, soc.build_name + ".svf"))
if __name__ == "__main__":
main()