Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial structure with gateware directory to store cores sources. #176

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .bsp/sbt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"sbt","version":"1.6.0","bspVersion":"2.0.0-M5","languages":["scala"],"argv":["/usr/lib/jvm/java-11-openjdk-amd64/bin/java","-Xms100m","-Xmx100m","-classpath","/home/dlobato/.local/share/JetBrains/IdeaIC2022.2/Scala/launcher/sbt-launch.jar","-Dsbt.script=/usr/bin/sbt","xsbt.boot.Boot","-bsp"]}
28 changes: 27 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,32 @@
debug.log

.vscode
.idea
obj_dir
*.fst
imgui.ini
imgui.ini

build

*.d
*.o
*.bin
*.elf
*.map

*.egg-info/

# sbt specific
.cache/
.history/
.lib/
dist/*
target
lib_managed/
src_managed/
project/boot/
project/plugins/project/

simWorkspace/
tmp/
null
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
19 changes: 19 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ThisBuild / version := "1.0"
ThisBuild / scalaVersion := "2.12.16"
ThisBuild / organization := "org.jderobot"

val spinalVersion = "1.7.3"
val spinalCore = "com.github.spinalhdl" %% "spinalhdl-core" % spinalVersion
val spinalLib = "com.github.spinalhdl" %% "spinalhdl-lib" % spinalVersion
val spinalIdslPlugin = compilerPlugin("com.github.spinalhdl" %% "spinalhdl-idsl-plugin" % spinalVersion)
val scalatest = "org.scalatest" %% "scalatest-funsuite" % "3.2.14" % "test"

lazy val mylib = (project in file("."))
.settings(
name := "fpga-robotics",
Compile / scalaSource := baseDirectory.value / "gateware" / "main" / "scala",
Test / scalaSource := baseDirectory.value / "gateware" / "test" / "scala",
libraryDependencies ++= Seq(spinalCore, spinalLib, spinalIdslPlugin)
)

fork := true
229 changes: 229 additions & 0 deletions designs/cam_to_hdmi/radiona_ulx3s.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
#!/usr/bin/env python3
from litex.build.generic_platform import Subsignal, Pins, IOStandard, Misc
from litex.soc.cores.bitbang import I2CMaster
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2018-2019 Florent Kermarrec <[email protected]>
# Copyright (c) 2018 David Shah <[email protected]>
# SPDX-License-Identifier: BSD-2-Clause

from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer

from litex.build.io import DDROutput, SDROutput

from litex_boards.platforms import radiona_ulx3s

from litex.build.lattice.trellis import trellis_args, trellis_argdict

from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.video import VideoHDMIPHY
from litex.soc.cores.led import LedChaser
from litex.soc.cores.spi import SPIMaster
from litex.soc.cores.gpio import GPIOOut

from litedram import modules as litedram_modules
from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY

#from fpga_robotics.cores.video.ov7670 import OV7670


# CRG ----------------------------------------------------------------------------------------------

class _CRG(Module):
def __init__(self, platform, sys_clk_freq, with_usb_pll=False, with_video_pll=False, sdram_rate="1:1"):
self.rst = Signal()
self.clock_domains.cd_sys = ClockDomain()
if sdram_rate == "1:2":
self.clock_domains.cd_sys2x = ClockDomain()
self.clock_domains.cd_sys2x_ps = ClockDomain()
else:
self.clock_domains.cd_sys_ps = ClockDomain()

# # #

# Clk / Rst
clk25 = platform.request("clk25")
rst = platform.request("rst")

# PLL
self.submodules.pll = pll = ECP5PLL()
self.comb += pll.reset.eq(rst | self.rst)
pll.register_clkin(clk25, 25e6)
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=90)

# USB PLL
if with_usb_pll:
self.submodules.usb_pll = usb_pll = ECP5PLL()
self.comb += usb_pll.reset.eq(rst | self.rst)
usb_pll.register_clkin(clk25, 25e6)
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)

# Video PLL
if with_video_pll:
self.submodules.video_pll = video_pll = ECP5PLL()
self.comb += video_pll.reset.eq(rst | self.rst)
video_pll.register_clkin(clk25, 25e6)
self.clock_domains.cd_hdmi = ClockDomain()
self.clock_domains.cd_hdmi5x = ClockDomain()
video_pll.create_clkout(self.cd_hdmi, 25e6, margin=0)
video_pll.create_clkout(self.cd_hdmi5x, 125e6, margin=0)

# VideoProc PLL
self.submodules.videoproc_pll = videoproc_pll = ECP5PLL()
self.comb += videoproc_pll.reset.eq(rst | self.rst)
videoproc_pll.register_clkin(clk25, 25e6)
self.clock_domains.cd_videoproc = ClockDomain()
self.clock_domains.cd_xclk = ClockDomain()
videoproc_pll.create_clkout(self.cd_videoproc, 100e6, margin=0)
videoproc_pll.create_clkout(self.cd_xclk, 25e6, margin=0)
self.specials += DDROutput(1, 0, platform.request("ov7670_xclk"), ClockSignal("xclk"))

self.clock_domains.cd_pclk = cd_pclk = ClockDomain()
self.comb += cd_pclk.clk.eq(platform.request("ov7670_pclk"))
self.specials += AsyncResetSynchronizer(cd_pclk, rst | self.rst)

# 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)

# Prevent ESP32 from resetting FPGA
self.comb += platform.request("wifi_gpio0").eq(1)

# BaseSoC ------------------------------------------------------------------------------------------

class BaseSoC(SoCCore):
def __init__(self, device="LFE5U-45F", revision="2.0", toolchain="trellis",
sys_clk_freq=int(50e6), sdram_module_cls="MT48LC16M16", sdram_rate="1:1",
with_led_chaser=True, with_video_terminal=False, with_video_framebuffer=False,
with_spi_flash=False, **kwargs):
platform = radiona_ulx3s.Platform(device=device, revision=revision, toolchain=toolchain)
platform.add_extension([
("i2c", 0,
Subsignal("scl", Pins("C6"), IOStandard("LVCMOS33"), Misc("DRIVE=4"), Misc("PULLMODE=UP")), # GP6
Subsignal("sda", Pins("C7"), IOStandard("LVCMOS33"), Misc("DRIVE=4"), Misc("PULLMODE=UP")) # GN6
),
("ov7670_xclk", 0, Pins("B11"), IOStandard("LVCMOS33")), # GP0
("ov7670_pclk", 0, Pins("N16"), IOStandard("LVCMOS33")),
("ov7670", 0,
Subsignal("href", Pins("N17"), IOStandard("LVCMOS33")),
Subsignal("vsync", Pins("P16"), IOStandard("LVCMOS33")),
Subsignal("data", Pins("C16 D16 B17 C17 B15 C15 C18 D17"), IOStandard("LVCMOS33")),
)
])

# CRG --------------------------------------------------------------------------------------
with_usb_pll = kwargs.get("uart_name", None) == "usb_acm"
with_video_pll = with_video_terminal or with_video_framebuffer
self.submodules.crg = _CRG(platform, sys_clk_freq, with_usb_pll, with_video_pll, sdram_rate=sdram_rate)

# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on ULX3S", **kwargs)

# 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"), sys_clk_freq)
self.add_sdram("sdram",
phy = self.sdrphy,
module = getattr(litedram_modules, sdram_module_cls)(sys_clk_freq, sdram_rate),
size = 0x40000000,
l2_cache_size = kwargs.get("l2_size", 8192)
)

# Video ------------------------------------------------------------------------------------
if with_video_terminal or with_video_framebuffer:
self.submodules.videophy = VideoHDMIPHY(platform.request("gpdi"), clock_domain="hdmi")
if with_video_terminal:
self.add_video_terminal(phy=self.videophy, timings="640x480@75Hz", clock_domain="hdmi")
if with_video_framebuffer:
self.add_video_framebuffer(phy=self.videophy, timings="640x480@75Hz", clock_domain="hdmi")

# SPI Flash --------------------------------------------------------------------------------
if with_spi_flash:
from litespi.modules import IS25LP128
from litespi.opcodes import SpiNorFlashOpCodes as Codes
self.add_spi_flash(mode="4x", module=IS25LP128(Codes.READ_1_1_4))

# Leds -------------------------------------------------------------------------------------
if with_led_chaser:
self.submodules.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)

# I2C --------------------------------------------------------------------------------------
pads = platform.request("i2c", 0)
self.submodules.i2c = I2CMaster(pads)

#ov7670_pads = platform.request("ov7670", 0)
#self.submodules.ov7670 = OV7670(pads = ov7670_pads, clock_domain="videoproc")



# Build --------------------------------------------------------------------------------------------

def main():
from litex.soc.integration.soc import LiteXSoCArgumentParser
parser = LiteXSoCArgumentParser(description="LiteX SoC on ULX3S")
target_group = parser.add_argument_group(title="Target options")
target_group.add_argument("--build", action="store_true", help="Build design.")
target_group.add_argument("--load", action="store_true", help="Load bitstream.")
target_group.add_argument("--toolchain", default="trellis", help="FPGA toolchain (trellis or diamond).")
target_group.add_argument("--device", default="LFE5U-45F", help="FPGA device (LFE5U-12F, LFE5U-25F, LFE5U-45F or LFE5U-85F).")
target_group.add_argument("--revision", default="2.0", help="Board revision (2.0 or 1.7).")
target_group.add_argument("--sys-clk-freq", default=50e6, help="System clock frequency.")
target_group.add_argument("--sdram-module", default="MT48LC16M16", help="SDRAM module (MT48LC16M16, AS4C32M16 or AS4C16M16).")
target_group.add_argument("--with-spi-flash", action="store_true", help="Enable SPI Flash (MMAPed).")
sdopts = target_group.add_mutually_exclusive_group()
sdopts.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support.")
sdopts.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support.")
target_group.add_argument("--with-oled", action="store_true", help="Enable SDD1331 OLED support.")
target_group.add_argument("--sdram-rate", default="1:1", help="SDRAM Rate (1:1 Full Rate or 1:2 Half Rate).")
viopts = target_group.add_mutually_exclusive_group()
viopts.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal (HDMI).")
viopts.add_argument("--with-video-framebuffer", action="store_true", help="Enable Video Framebuffer (HDMI).")
builder_args(parser)
soc_core_args(parser)
trellis_args(parser)
args = parser.parse_args()

soc = BaseSoC(
device = args.device,
revision = args.revision,
toolchain = args.toolchain,
sys_clk_freq = int(float(args.sys_clk_freq)),
sdram_module_cls = args.sdram_module,
sdram_rate = args.sdram_rate,
with_video_terminal = args.with_video_terminal,
with_video_framebuffer = args.with_video_framebuffer,
with_spi_flash = args.with_spi_flash,
**soc_core_argdict(args))
if args.with_spi_sdcard:
soc.add_spi_sdcard()
if args.with_sdcard:
soc.add_sdcard()
if args.with_oled:
soc.add_oled()

builder = Builder(soc, **builder_argdict(args))
builder_kargs = trellis_argdict(args) if args.toolchain == "trellis" else {}
if args.build:
builder.build(**builder_kargs)

if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(builder.get_bitstream_filename(mode="sram", ext=".svf")) # FIXME

if __name__ == "__main__":
main()
Loading