-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial structure with gateware directory to store cores sources.
Example SpinalHDL core handling ov7670 registered inputs Example litex firmware to access ov7670 control bus
- Loading branch information
Showing
229 changed files
with
3,229 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Oops, something went wrong.