In this guide, Iâll take you through the (sometimes frustrating) journey of integrating a custom RoCC accelerator with Chipyard. Please make sure youâre referencing Chipyardâs docs if you get stuck.
Warning: Be mindful of your Chipyard version. Iâm using v1.10.0âtrust me, it matters. Plus I am using Ubuntu!
- Head over to the Anaconda installer list and grab the one that matches your OS.
- Open your terminal, and letâs run this:
bash ~/Downloads/Anaconda3-<INSTALLER_VERSION>-Linux-x86_64.sh
- Type "yes" as needed (agree to that license, get your Anaconda initialized, etc.).
- The default install location? Right here:
PREFIX=/home/<USER>/anaconda3
source <PATH_TO_CONDA>/bin/activate
conda init
source ~/.bashrc
(By the way, still using bashrc
? Not zshrc
? Are you sure you donât wanna move on? Just saying...đ€Łđ€Łđ€Ł)
(Optional: Want your shell to auto-activate Anaconda every time it opens? Here you go:)
conda config --set auto_activate_base True
conda install -n base conda-libmamba-solver
conda config --set solver libmamba
conda activate base
-
Clone the Chipyard repo and check out the right version:
git clone https://github.com/ucb-bar/chipyard.git cd chipyard git checkout 1.10.0
-
Run the setup script and skip the extras (because time is precious):
./build-setup.sh riscv-tools -s 6 -s 7 -s 8 -s 9
-s 6
: Skips FireSim (only if you donât need it)-s 7
: Skips FireSim source pre-compilation (trust me, skip it)-s 8
: Skips FireMarshal (Fire what?)-s 9
: Skips FireMarshal Linux pre-compilation (weâve got other things to do)
-
After all that, source the environment script every time:
source ./env.sh
(Pro tip: Save yourself the trouble by creating an alias in
.bashrc
, still usingbashrc
?)alias chip="cd /home/USER/chipyard/ && source env.sh"
-
Structure your project directory like this:
Takhol/ build.sbt src/main/scala/Takhol.scala
-
Add the project settings to
build.sbt
:organization := "edu.berkeley.cs" version := "1.0" name := "Takhol" scalaVersion := "2.12.13"
-
Add Takhol to Chipyardâs
generators/
directory:cd generators/ git submodule add https://git-repository.com/Takhol.git git submodule update --recursive generators/Takhol
-
Link Takhol to Chipyardâs top-level
build.sbt
file:lazy val Takhol = (project in file("generators/Takhol")) .dependsOn(rocketchip) .settings(libraryDependencies ++= rocketLibDeps.value) .settings(commonSettings)
-
Add Takhol as a dependency in the sub-projects section:
lazy val chipyard = (project in file("generators/chipyard")) .dependsOn(testchipip, rocketchip, boom, hwacha, Takhol, ...) .settings(libraryDependencies ++= rocketLibDeps.value) .settings( libraryDependencies ++= Seq( "org.reflections" % "reflections" % "0.10.2" ) ) .settings(commonSettings)
sbt build
Find the RocketConfigs.scala
file (maybe in chipyard/generators/chipyard/src/main/scala/config/
) and add your custom config:
class TakholRocketConfig extends Config (
new Takhol.WithTakhol ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core
new chipyard.config.AbstractConfig
)
If the command above seems unclear, and you're unfamiliar with configuring settings in Chipyard or Chisel projects, let me provide a brief overview.
Imagine that in your Takhol.scala file, you define a set of parameters such as rows and columns. To manage these parameters more effectively, you can create a new file named config.scala. This file would look something like this:
package Takhol
import org.chipsalliance.cde.config._
class WithTakhol extends Config((site, here, up) => {
case TakholKey => TakholParams(
rows = 4,
columns = 4
)
})
Now, you can use these parameters directly in your Takhol.scala file. Your Takhol.scala might look something like this:
package Takhol
import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config._
case class TakholParams(
rows: Int,
columns: Int)
case object TakholKey extends Field[TakholParams]
abstract trait TakholParameters {
implicit val p: Parameters
val takholParams = p(TakholKey)
val rows = takholParams.rows
val columns = takholParams.columns
}
You now have rows
and columns
in Takhol.scala
that you can use them as you wish.
-
Inside
chipyard/sims/verilator
, create a folder for your program:mkdir src cd src touch hello_world.c
-
Write your first RISC-V program in
hello_world.c
(simple and classic):#include <stdio.h> int main(void) { printf("Hello, World!\n"); return 0; }
-
Build the program:
riscv64-unknown-elf-gcc -fno-common -fno-builtin-printf -specs=htif_nano.specs -c hello_world.c riscv64-unknown-elf-gcc -static -specs=htif_nano.specs hello_world.o -o hello_world.riscv spike hello_world.riscv
If you are lazy like me, create a
run.sh
script to compile and test your code with all baremetal programs:#!/bin/bash if [ -z "$1" ]; then echo "Usage: sh file.sh <filename.c>" exit 1 fi filename=$(basename "$1" .c) echo "riscv64-unknown-elf-gcc -fno-common -fno-builtin-printf -specs=htif_nano.specs -c $filename.c" riscv64-unknown-elf-gcc -fno-common -fno-builtin-printf -specs=htif_nano.specs -c "$filename.c" -o "$filename.o" echo "riscv64-unknown-elf-gcc -static -specs=htif_nano.specs $filename.o -o $filename.riscv" riscv64-unknown-elf-gcc -static -specs=htif_nano.specs "$filename.o" -o "$filename.riscv" echo "spike $filename.riscv" spike "$filename.riscv" rm "$filename.o"%
and then run it:
chmod +x run.sh ./run.sh hello_world.c
(If you get an error about
htif_nano.specs
, you missed sourcingenv.sh
earlier. Go back, fix it, and try again!) -
Run the simulation with VCD output (yes, youâll want this):
make CONFIG=TakholRocketConfig BINARY=src/hello_world.riscv run-binary-debug
Check the output folder for simulation results, including the .vcd
file. If you see âHello, World!â on your terminal, rejoiceâeverything works. If not... well, you know where to look.
Congrats! Youâre now fully set up to experiment and debug your custom accelerator in Chipyard. Enjoy the chaos and the code!