Skip to content

Latest commit

 

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shake-fpga

Shake-based build system for Haskell-based FPGA projects, featuring:

  1. clash as HDL
  2. verilator for simulation and testing
  3. vivado for synthesis and bitstream generation

How to use

Including shake-fpga in your project

Currently, shake-fpga is yet to be published on Hackages, so you will need to include it in your cabal.project file as follows:

source-repository-package
  type: git
  location: https://github.com/poscat0x04/shake-fpga
  tag: 1a202b258db7f19cfea4fc5a8ca9bae84333f374

You should also clone the repository and do a cabal install exe:shake-fpga to install the shake-fpga executable.

Preparing your project for shake-fpga

After you've included shake-fpga in your project, you can now configure your project to use shake-fpga

The first thing you want to do is to add

write-ghc-environment-files: always

to your cabal.project file, since the ghc environment file is required for clash to function.

Then you should include clash-prelude, ghc-typelits-extra, ghc-typelits-knownnat, ghc-typelits-natnormalise in your .cabal file as library dependencies(build-depends). Also enable these plugins like so:

library
  ghc-options:
    -fplugin GHC.TypeLits.Extra.Solver
    -fplugin GHC.TypeLits.Normalise
    -fplugin GHC.TypeLits.KnownNat.Solver

Now run a cabal build to generate the ghc environment file needed by clash.

Once the environment file is generated, you can proceed to configuring shake-fpga.yaml

The shake-fpga.yaml has the following structure:

hdl: <hdl to target, verilog/systemverilog or vhdl>
targets:
  - module: <Haskell module name>
    alias: <alias for target>
    topEntity: <top entity (i.e. function) name>
    part: <chip part>
    xdc: <path to xdc file>
    linkComponents:
      - test:<name of test>

You can have multiple targets in a single cabal package.

Building with shake-fpga

To show the avaiable targets given a shake-fpga.yaml, run shake-fpga -- -h

A typical output would look something like the following:

Targets:
  - clean
  - _build/Adder/deps.mk
  - _build/Adder/wire/clash/clash-manifest.json
  - _build/Adder/wire/vivado/synth+implement.tcl
  - _build/Adder/wire/vivado/out.bit
  - _build/Adder/wire/verilator/libVmodel.a
  - _build/Adder/wire/verilator/libverilated.a
  - _build/Adder/wire/verilator/Vmodel-c.h
  - _build/Adder/wire/verilator/Vmodel-c.cpp
  - _build/Adder/wire/verilator/Vmodel-c.o
  - _build/Adder/wire/verilated/libVmodel-c.a
  - _build/Adder/wire/verilated/Vmodel-c.o
  - _build/Adder/wire/haskellBinding/Verilated.hsc
  - adder:bit
  - adder:verilate
  - adder:clash
  - adder
  1. clean is a phony rule that removes the _build directory
  2. _build/Adder/deps.mk is a makefile generated by clash that contains the .hs dependencies of the target Haskell module, and is used by shake to trigger rebuilds.
  3. _build/Adder/wire/clash/clash-manifest.json is a JSON file generated by clash that contains information about the top module (e.g. its name, ports, and types). It is used by shake to generate binding to the verilated model.
  4. _build/Adder/wire/vivado/synth+implement.tcl is a TCL script generated by shake-fpga that runs the synthesis and implementation flow in Vivado.
  5. _build/Adder/wire/vivado/out.bit is the bitstream file generated by Vivado after the synthesis and implementation flow.
  6. _build/Adder/wire/verilator/libVmodel.a is the verilated model of the top module, and _build/Adder/wire/verilator/libverilated.a is the runtime for the verilated model. Both are generated via a single invocation of verilator. (see also: https://verilator.org/guide/latest/files.html)
  7. _build/Adder/wire/verilator/Vmodel-c.h, _build/Adder/wire/verilator/Vmodel-c.cpp and _build/Adder/wire/verilator/Vmodel-c.o are the c++ header, source and object files generated respectively. It is a thin wrapper that translate the c++ interface to a c interface that Haskell can interact with.
  8. _build/Adder/wire/verilated/libVmodel-c.a is the combined archive of verilator/Vmodel-c.o, libVmodel.a and libverilated.a, whereas _build/Adder/wire/verilated/Vmodel-c.o is the combined object file of the three.
  9. _build/Adder/wire/haskellBinding/Verilated.hsc is the hsc2hs binding to Vmodel-c
  10. adder:bit is a phony rule that builds the bitstream using the TCL script.
  11. adder:verilate is a phony rule that builds Vmodel-c
  12. adder:clash is a phony rule that runs the clash compilation for the top entity/function.

Verification with shake-fpga

If you'd like to verify your design in Haskell, you should use fpgaHooks in your Setup.hs file. What it does is it injects 2 hooks into the build process: one before the configuration process that essentially adds various fields to your .cabal file that are needed to run the verilated model in Haskell, and one after the configuration process that builds the verilated model as well as the Haskell binding (module name is Verilated). Note that the configuration filename is non-configurable and is always shake-fpga.yaml

To do this, use the following SetupHooks.hs file:

module SetupHooks (setupHooks) where

import Distribution.FPGA.Hooks

setupHooks = fpgaHooks

as well as set the following options in your .cabal file:

build-type:      Hooks

custom-setup
  setup-depends:
    , base
    , shake-fpga

Assumptions/Dependencies

The following cli tools should be in PATH:

  • vivado: if you want to build bitstreams
  • verilator, pkg-config and c/c++ compilers: if you want to build the verilated models

Additionally the following libraries are required for verilated models:

  • lz4
  • zlib

The program should be run from the project root.

A shake-fpga.yaml file should be present in the project root.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages