Skip to content
Open
Show file tree
Hide file tree
Changes from 12 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 projects/orangecrab-nix/.envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
8 changes: 8 additions & 0 deletions projects/orangecrab-nix/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
01-clash/
02-hdl/
03-net/
04-bitstream/
_build/
dist-newstyle/
.ghc.environment.*
*.local
21 changes: 21 additions & 0 deletions projects/orangecrab-nix/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 QBayLogic B.V.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
48 changes: 48 additions & 0 deletions projects/orangecrab-nix/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# OrangeCrab Development Setup

This sub-project contains some demo applications for targeting the [OrangeCrab FPGA r0.2.1](https://orangecrab-fpga.github.io/orangecrab-hardware/docs/r0.2.1) in combination with the OrangeCrab Pmod / Debug Expander board and an [Adafruit FT232H JTAG Debugger](https://learn.adafruit.com/adafruit-ft232h-breakout).

It can to be used as a rapid prototyping template or as a starter for larger project setups.

## Build Architecture

The setup uses a combination of `cabal` and `make`, where
* `cabal` is used to handle everything Haskell / Clash related up till the point of generating HDL via running the `clash` compiler itself, and
* `make` is used to run `clash`, RTL synthesis, Place and Route, and for programming the FPGA.

### Cabal

In terms of Haskell / Clash package management, everything is fairly standard. Have a look at the [`orangecrab.cabal`](orangecrab.cabal) and the [`cabal.project`](../cabal.project) files for the particular details.

### Make

A straightforward [`makefile`](makefile) is used on top of `cabal` to handle any additional calls which are not covered by the cabal build system yet.

#### Configuration

The `makefile` includes the additional configuration file [`build.cfg`](build.cfg), which can be used to link all of the required external build tools. To this end, simply copy the file to `build.cfg.local` on your local machine and modify it towards your personal needs. Any changes made to the copy will be preferred in comparison to original `build.cfg`. Just leave out the overrides, if you like to stick with the defaults instead.

Some references on where to get all of the required external tooling are also given as part of the configuration file.

The particular top entity to be built can be selected via overriding the `NAME` parameter in the `build.cfg.local`. Just set it to the name of the file in the `src` directory shall be built (without the `.hs` ending). See the `makefile` for the pre-configured default.

#### Usage

The `makefile` offers the follwing commands (to be invoked via `make CMD`) where each command depends on the output generated by all of the former ones according to the order of the list below. The `bitstream` command is the `make` default.

| CMD | Description |
| ----------- | --------------------------------------------------- |
| `hdl` | generates Verilog code from the selected TopEntity |
| `synth` | runs RTL synthesis |
| `netlist` | runs Place and Route |
| `bitstream` | generates a bitstream to be transferred to the FPGA |
| `upload` | copies the generated bitstream to FPGA |

The output of each command is stored in a corresponding sub-directory within an automatically created `_build` folder. Use `make clean`, if you like to rebuild everything in the `_build` folder from scratch (`make clean` does **not** run `cabal clean`).

## Demo Applications

### Blink

Simple blinking example using the RGB LED on the OrangeCrab r0.2.1 board.

1 change: 1 addition & 0 deletions projects/orangecrab-nix/bin
38 changes: 38 additions & 0 deletions projects/orangecrab-nix/build.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
###############################################################################
# Copyright : Copyright © 2024 QBayLogic B.V.
# License : MIT
# Maintainer : QBayLogic B.V.
# Stability : experimental
# Portability : POSIX
#
# Required tooling for targeting the OrangeCrab r0.2.1 in combination with
# the Pmod/Debug Expander board. Don't modify this file directly. Instead,
# copy it to `build.cfg.local` and introduce any required changes there.
###############################################################################

CFG_PATH:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))

###############################################################################

# https://cabal.readthedocs.io/en/stable
CABAL=cabal

# https://github.com/clash-lang/clash-compiler
CLASH=clash

# https://github.com/cliffordwolf/yosys
YOSYS=yosys

# https://github.com/YosysHQ/nextpnr
PNR=nextpnr-ecp5

# https://prjtrellis.readthedocs.io
PACK=ecppack

# https://github.com/gregdavill/ecpprog
PROG=ecpprog

# https://dfu-util.sourceforge.net (optional)
DFUSUFFIX=dfu-suffix

###############################################################################
5 changes: 5 additions & 0 deletions projects/orangecrab-nix/cabal.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
packages:
orangecrab.cabal

write-ghc-environment-files: always

130 changes: 130 additions & 0 deletions projects/orangecrab-nix/flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions projects/orangecrab-nix/flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
description = "A flake enabling tooling for orangecrab";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
ecpprog.url = "github:diegodiv/ecpprog";
};
outputs = { self, nixpkgs, flake-utils, ecpprog, ... }:
flake-utils.lib.eachDefaultSystem (system:
let pkgs = nixpkgs.legacyPackages.${system};
serialportSrc = pkgs.fetchFromGitHub {
owner = "standardsemiconductor";
repo = "serialport";
rev = "ce42a5afebb55d2e2e84be7f5386d69c343e3942";
sha256 = "sha256-oBG8DylFwzUu212AiNOg2x+D1jmI2hAvMJQT0F8wWlE=";
};
clashCompilerSrc = pkgs.fetchFromGitHub {
owner = "clash-lang";
repo = "clash-compiler";
rev = "7bf85bfbdb6561c068f99ec5f346d1b5092a011b";
sha256 = "sha256-uiXDG8S5eJrQvwetU0YlAKu1C5RDFoW/3/j77nM0lYw=";
};

inherit (pkgs.haskell.lib) dontCheck doJailbreak markUnbroken;
overlay = final: prev: {
clash-prelude = prev.callCabal2nix "clash-prelude"
(clashCompilerSrc + "/clash-prelude") { };
clash-prelude-hedgehog = prev.callCabal2nix "clash-prelude-hedgehog"
(clashCompilerSrc + "/clash-prelude-hedgehog") { };
clash-lib = dontCheck (doJailbreak (prev.callCabal2nix "clash-lib"
(clashCompilerSrc + "/clash-lib") { }));
clash-ghc = prev.callCabal2nix "clash-ghc"
(clashCompilerSrc + "/clash-ghc") { };
serialport = dontCheck (prev.callCabal2nix "serialport" serialportSrc { });
hint = doJailbreak prev.hint;
string-interpolate = doJailbreak prev.string-interpolate;
orangecrab = final.callCabal2nix "orangecrab" ./. { };
};
myHsPkgs = pkgs.haskell.packages.ghc9101.extend overlay;
in
{
devShells.default = myHsPkgs.shellFor {
name = "GHC 9.10.1";
packages = p: [ p.orangecrab ];
inputsFrom = [];
nativeBuildInputs =
with pkgs; [
gnumake yosys nextpnr trellis
] ++
(with myHsPkgs; [ cabal-install ])
++ [ecpprog.defaultPackage.${system}]
;
};
packages.default = dontCheck myHsPkgs.orangecrab;
});
}
78 changes: 78 additions & 0 deletions projects/orangecrab-nix/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
##----------------------------------------------------------------------------##
# Project Settings #
##----------------------------------------------------------------------------##

NAME = Blink
TOP = topEntity
BUILDDIR= _build
PNR_FLAGS= \
--85k \
--package CSFBGA285 \
--lpf orangecrab.pcf \

-include build.cfg
-include build.cfg.local

##----------------------------------------------------------------------------##
# Build Rules #
##----------------------------------------------------------------------------##

default: bitstream

upload: ${BUILDDIR}/04-bitstream/${TOP}.bit
${PROG} -S $<

hdl: ${BUILDDIR}/02-hdl/${TOP}.v

synth: ${BUILDDIR}/03-net/$(TOP).json

netlist: ${BUILDDIR}/04-bitstream/$(TOP).config

bitstream: ${BUILDDIR}/04-bitstream/$(TOP).bit

${BUILDDIR}/04-bitstream/${TOP}.dfu: ${BUILDDIR}/04-bitstream/${TOP}.bit
cp -a $< $@
${DFUSUFFIX} -v 1209 -p 5af0 -a $@

${BUILDDIR}/04-bitstream/${TOP}.bit: ${BUILDDIR}/04-bitstream/${TOP}.config
${PACK} --compress --freq 38.8 --input $< --bit $@

${BUILDDIR}/04-bitstream/$(TOP).config: ${BUILDDIR}/03-net/$(TOP).json
mkdir -p ${BUILDDIR}/04-bitstream
${PNR} --json $< --textcfg $@ ${PNR_FLAGS}

${BUILDDIR}/03-net/$(TOP).json: ${BUILDDIR}/02-hdl/${TOP}.v
mkdir -p ${BUILDDIR}/03-net ${BUILDDIR}/log
$(YOSYS) \
-l ${BUILDDIR}/log/synth.log \
-p 'read_verilog $(dir $^)/*.v; synth_ecp5 -top $(TOP) -json $@'

${BUILDDIR}/02-hdl/${TOP}.v: src/${NAME}.hs dist-newstyle/packagedb src/*
${CABAL} build
mkdir -p ${BUILDDIR}/01-clash
echo
${CABAL} run clash -- \
-package-env $(abspath).ghc.environment.* \
--verilog \
-outputdir ${BUILDDIR}/01-clash \
$<
rm -Rf ${BUILDDIR}/02-hdl
mv ${BUILDDIR}/01-clash/${NAME}.topEntity ${BUILDDIR}/02-hdl

dist-newstyle/packagedb:
${CABAL} build

##----------------------------------------------------------------------------##
# Cleanup #
##----------------------------------------------------------------------------##

clean:
rm -Rf ${BUILDDIR}

##----------------------------------------------------------------------------##
# Special Targets #
##----------------------------------------------------------------------------##

.PHONY: clean nano4k upload nano4k-upload
.SECONDARY:
.SILENT:
Loading
Loading