Chisel is an open-source hardware construction language developed at UC Berkeley that supports advanced hardware design using highly parameterized generators and layered domain-specific hardware languages.
You can find code examples on the Berkeley EECS Berkeley Architecture Research (BAR) github page. Chisel-tutorial is a set of sample circuits with supporting documentation. Sodor is a set of educational processors written in Chisel by Christopher Celio, a PhD student at UC Berkeley. Sodor implements the RISC-V Instruction Set Architecture designed in the BAR group and described on riscv.org.
import Chisel._
class GCD extends Module {
val io = new Bundle {
val a = UInt(INPUT, 16)
val b = UInt(INPUT, 16)
val e = Bool(INPUT)
val z = UInt(OUTPUT, 16)
val v = Bool(OUTPUT)
}
val x = Reg(UInt())
val y = Reg(UInt())
when (x > y) { x := x - y }
unless (x > y) { y := y - x }
when (io.e) { x := io.a; y := io.b }
io.z := x
io.v := y === UInt(0)
}
object Example {
def main(args: Array[String]): Unit = {
chiselMain(args, () => Module(new GCD()))
}
}
import Chisel._ // importing the Chisel library.
/// Creating a Module that computes the maximum of N values
//
// This generator shows how it is possible to do functional construction
// of circuits.
class MaxN(n: Int, w: Int /* parameterized input */) extends Module {
private def Max2(x: UInt, y: UInt) = Mux(x > y, x, y)
val io = new Bundle {
val in = Vec.fill(n){ UInt(INPUT, w) }
val out = UInt(OUTPUT, w)
}
io.out := io.in.reduceLeft(Max2)
}
object MaxNExample {
// Main Entry Point of the circuit generator
def main(args: Array[String]): Unit = {
// instantiate with 4 ports. Each port is 8 bits wide.
chiselMain(args, () => Module(new MaxN(4, 8)))
}
}
/** Four-by-four multiply using a look-up table.
*/
class Mul extends Module {
val io = new Bundle {
val x = UInt(INPUT, 4)
val y = UInt(INPUT, 4)
val z = UInt(OUTPUT, 8)
}
val muls = new ArrayBuffer[UInt]()
for (i <- 0 until 16)
for (j <- 0 until 16)
muls += UInt(i * j, width = 8)
val tbl = Vec(muls)
io.z := tbl((io.x << UInt(4)) | io.y)
}
/** A n-bit adder with carry in and carry out
*/
class Adder(val n:Int) extends Module {
val io = new Bundle {
val A = UInt(INPUT, n)
val B = UInt(INPUT, n)
val Cin = UInt(INPUT, 1)
val Sum = UInt(OUTPUT, n)
val Cout = UInt(OUTPUT, 1)
}
//create a vector of FullAdders
val FAs = Vec.fill(n){ Module(new FullAdder()).io }
val carry = Vec.fill(n+1){ UInt(width = 1) }
val sum = Vec.fill(n){ Bool() }
//first carry is the top level carry in
carry(0) := io.Cin
//wire up the ports of the full adders
for (i <- 0 until n) {
FAs(i).a := io.A(i)
FAs(i).b := io.B(i)
FAs(i).cin := carry(i)
carry(i+1) := FAs(i).cout
sum(i) := FAs(i).sum.toBool()
}
io.Sum := sum.toBits().toUInt()
io.Cout := carry(n)
}
Getting started with Chisel is easy. Boilerplate verilog often directly maps to Chisel one-liners. Everything you learn to write Scala code is directly applicable. Follow the Chisel Tutorial. When you have a question that the documentation doesn't answer, check Stack Overflow or ask on the Chisel users mailing list.
Chisel is released as a JAR file through the official Maven repo. Just add this line to your build.sbt
libraryDependencies += "edu.berkeley.cs" %% "chisel" % "latest.release"
If you are new to Scala and have no idea what that means, follow the step-by-step in Chisel's README.md.
Also see: slides from the second Chisel bootcamp.