SkillAgentSearch skills...

Chisel

Chisel: A Modern Hardware Design Language

Install / Use

/learn @chipsalliance/Chisel
About this skill

Quality Score

0/100

Category

Design

Supported Platforms

Universal

README

<a href="https://www.chisel-lang.org"> <img src="https://raw.githubusercontent.com/chipsalliance/chisel/main/docs/src/images/chisel_logo.svg?sanitize=true" height="60"> </a> <a href="https://www.chipsalliance.org"> <img align="right" src="https://raw.githubusercontent.com/chipsalliance/.github/main/profile/images/chips_alliance.svg?sanitize=true" height="60"> </a>

The Constructing Hardware in a Scala Embedded Language (Chisel) is an open-source hardware description language (HDL) used to describe digital electronics and circuits at the register-transfer level that facilitates advanced circuit generation and design reuse for both ASIC and FPGA digital logic designs.

Chisel adds hardware construction primitives to the Scala programming language, providing designers with the power of a modern programming language to write complex, parameterizable circuit generators that produce synthesizable Verilog. This generator methodology enables the creation of re-usable components and libraries, such as the FIFO queue and arbiters in the Chisel Standard Library, raising the level of abstraction in design while retaining fine-grained control.

For more information on the benefits of Chisel see: "What benefits does Chisel offer over classic Hardware Description Languages?"

Chisel is powered by FIRRTL (Flexible Intermediate Representation for RTL), a hardware compiler framework implemented by LLVM CIRCT.

Chisel is permissively licensed (Apache 2.0) under the guidance of CHIPS Alliance.


Join the chat at https://gitter.im/freechipsproject/chisel3 Scaladoc CI GitHub tag (latest SemVer) Scala version support

What does Chisel code look like?

LED blink

import chisel3._
import chisel3.util.Counter
import circt.stage.ChiselStage

class Blinky(freq: Int, startOn: Boolean = false) extends Module {
  val io = IO(new Bundle {
    val led0 = Output(Bool())
  })
  // Blink LED every second using Chisel built-in util.Counter
  val led = RegInit(startOn.B)
  val (_, counterWrap) = Counter(true.B, freq / 2)
  when(counterWrap) {
    led := ~led
  }
  io.led0 := led
}

object Main extends App {
  // These lines generate the Verilog output
  println(
    ChiselStage.emitSystemVerilog(
      new Blinky(1000),
      firtoolOpts = Array("-disable-all-randomization", "-strip-debug-info")
    )
  )
}

Should output the following Verilog:

<!-- Note that you can regenerate the HTML below by using VSCode with extensions: * Markdown All in One: https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one * Verilog-HDL/SystemVerilog/Bluespec SystemVerilog: https://marketplace.visualstudio.com/items?itemName=mshr-h.VerilogHDL You then generate the Verilog and place it in a syntax highlighted code block in this file, eg. ```verilog ... ``` You can then run the command: > Markdown All in One: Print current document to HTML Then you can open the generated HTML and copy-paste --> <details> <summary>Click to expand!</summary>

</code></pre>

<pre><code class="language-verilog"><span class="hljs-comment">// Generated by CIRCT firtool-1.37.0</span> <span class="hljs-keyword">module</span> Blinky( <span class="hljs-keyword">input</span> clock, reset, <span class="hljs-keyword">output</span> io_led0 ); <span class="hljs-keyword">reg</span> led; <span class="hljs-keyword">reg</span> [<span class="hljs-number">8</span>:<span class="hljs-number">0</span>] counterWrap_c_value; <span class="hljs-keyword">always</span> @(<span class="hljs-keyword">posedge</span> clock) <span class="hljs-keyword">begin</span> <span class="hljs-keyword">if</span> (reset) <span class="hljs-keyword">begin</span> led &lt;= <span class="hljs-number">1&#x27;h0</span>; counterWrap_c_value &lt;= <span class="hljs-number">9&#x27;h0</span>; <span class="hljs-keyword">end</span> <span class="hljs-keyword">else</span> <span class="hljs-keyword">begin</span> <span class="hljs-keyword">automatic</span> <span class="hljs-keyword">logic</span> counterWrap = counterWrap_c_value == <span class="hljs-number">9&#x27;h1F3</span>; led &lt;= counterWrap ^ led; <span class="hljs-keyword">if</span> (counterWrap) counterWrap_c_value &lt;= <span class="hljs-number">9&#x27;h0</span>; <span class="hljs-keyword">else</span> counterWrap_c_value &lt;= counterWrap_c_value + <span class="hljs-number">9&#x27;h1</span>; <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-comment">// always @(posedge)</span> <span class="hljs-keyword">assign</span> io_led0 = led; <span class="hljs-keyword">endmodule</span> </code></pre> </details>

FIR Filter

Consider an FIR filter that implements a convolution operation, as depicted in this block diagram:

<img src="https://raw.githubusercontent.com/chipsalliance/chisel/main/docs/src/images/fir_filter.svg?sanitize=true" width="512" />

While Chisel provides similar base primitives as synthesizable Verilog, and could be used as such:

// 3-point moving sum implemented in the style of a FIR filter
class MovingSum3(bitWidth: Int) extends Module {
  val io = IO(new Bundle {
    val in = Input(UInt(bitWidth.W))
    val out = Output(UInt(bitWidth.W))
  })

  val z1 = RegNext(io.in)
  val z2 = RegNext(z1)

  io.out := (io.in * 1.U) + (z1 * 1.U) + (z2 * 1.U)
}

the power of Chisel comes from the ability to create generators, such as an FIR filter that is defined by the list of coefficients:

// Generalized FIR filter parameterized by the convolution coefficients
class FirFilter(bitWidth: Int, coeffs: Seq[UInt]) extends Module {
  val io = IO(new Bundle {
    val in = Input(UInt(bitWidth.W))
    val out = Output(UInt(bitWidth.W))
  })
  // Create the serial-in, parallel-out shift register
  val zs = Reg(Vec(coeffs.length, UInt(bitWidth.W)))
  zs(0) := io.in
  for (i <- 1 until coeffs.length) {
    zs(i) := zs(i-1)
  }

  // Do the multiplies
  val products = VecInit.tabulate(coeffs.length)(i => zs(i) * coeffs(i))

  // Sum up the products
  io.out := products.reduce(_ + _)
}

and use and re-use them across designs:

val movingSum3Filter = Module(new FirFilter(8, Seq(1.U, 1.U, 1.U)))  // same 3-point moving sum filter as before
val delayFilter = Module(new FirFilter(8, Seq(0.U, 1.U)))  // 1-cycle delay as a FIR filter
val triangleFilter = Module(new FirFilter(8, Seq(1.U, 2.U, 3.U, 2.U, 1.U)))  // 5-point FIR filter with a triangle impulse response

The above can be converted to Verilog using ChiselStage:

import chisel3.stage.ChiselGeneratorAnnotation
import circt.stage.{ChiselStage, FirtoolOption}

(new ChiselStage).execute(
  Array("--target", "systemverilog"),
  Seq(ChiselGeneratorAnnotation(() => new FirFilter(8, Seq(1.U, 1.U, 1.U))),
    FirtoolOption("--disable-all-randomization"))
)

Alternatively, you may generate some Verilog directly for inspection:

val verilogString = chisel3.getVerilogString(new FirFilter(8, Seq(0.U, 1.U)))
println(verilogString)

Getting Started

Bootcamp Interactive Tutorial

The online Chisel Bootcamp is the recommended way to get started with and learn Chisel. No setup is required (it runs in the browser), nor does it assume any prior knowledge of Scala.

The classic Chisel tutorial contains small exercises and runs on your computer.

A Textbook on Chisel

If you like a textbook to learn Chisel and also a bit of digital design in general, you may be interested in reading Digital Design with Chisel. It is available in English, Chi

View on GitHub
GitHub Stars4.6k
CategoryDesign
Updated8h ago
Forks651

Languages

Scala

Security Score

100/100

Audited on Mar 31, 2026

No findings